Multithreaded Caches Implementation

The base class for cached data and the cache manager class are defined in the tool_multithreading.h file.

Cache Manager CacheManager

The cache manager is defined as a template class CacheManager working with cached data and includes the members:

  • longTerm – data of the main thread; is used in serial execution and to initialize data of multithreaded caches.

  • tcache – a list of caches with data which are used in parallel calculations. Each thread uses only its own copy of the data which is available by the thread identifier threadKey. For multithreaded processing of dependent (with shared data) objects, the mtm_Items multithreading mode or higher should be used.

  • lock – cache manager lock which is used when selecting caches and changing the main thread cache.

The template class CacheManager<class T> implements the methods:

  • T * operator() – returns a pointer to the cached data of the current thread. Always returns non-null value.

  • void Reset( bool resetLongTerm ) – invalidates caches. If resetLongTerm == true, deletes the main thread cache.

  • void CleanAll( bool doPostproc, bool force ) – deletes all caches and unsubscribes from the garbage collection. Should be called in sequential code.

  • T * LongTerm() – returns a pointer to cached data of the main thread. Always returns non-null value. All operations with the main thread cache should be protected by the cache manager lock.

  • CommonMutex * GetLock() – returns a pointer to the lock for operations with the main thread cache, considering whether the code runs in parallel. Can return null value (good for use with ScopedLock).

  • CommonMutex * GetLockHard() – returns a pointer to the lock for operations with the main thread cache. Always returns non-null value.

  • bool ResetCacheData() – cleaning function, used by the garbage collector.

The cache manager algorithm depends on the kernel multithreading mode MbeMultithreadedMode.

If the kernel multithreading mode is defined as mtm_SafeItems or higher, the cache manager initiates use of dedicated cache for each thread. In this case, the cache manager selects a copy of cached data for a thread by its thread ID.

After switching to serial execution the cache manager calls a Postprocess() function for caches post-processing. The specified function iterates through the caches used in parallel computing and calls the function longTerm.MergeWith() with the data of each cache as a parameter. After the function Postprocess() finishes the caches are destroyed. Then, when a cache is requested, the cache manager returns the main thread cache (longTerm).

The CacheManager class is derived from the CacheCleaner class, which allows cleaning caches on demand.

Base Cached Data Class AuxiliaryData

Any cached data class should be derived from the base class AuxiliaryData and contain default constructor and copy constructor.

Also, if caches post-processing is needed after exiting parallel calculations, a cached data class should override the method void MergeWith( AuxiliaryData * ), which is called by the cache manager for the main cache with the data of each cache as a parameter. Default implementation of MergeWith() does not perform any post-processing.

An object class that needs data caching should define its cached data as a class derived from the AuxiliaryData class and include an instance of CacheManager as a class member.

For parallel processing of dependent (with shared data) objects the kernel multithreading mode mtm_SafeItems or higher should be used.