Hi Gael,
I think the most efficient solution would be to use atomics. I am not
sure whether the code below is allowed and fixes the problem
#pragma omp atomic
static std::ptrdiff_t m_l1CacheSize =
manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024);
#pragma omp atomic
static std::ptrdiff_t m_l2CacheSize =
manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024);
Another alternative might be #pragma omp critical.
Yet another idea might be to look at 'atomic_do_once' (see [1] and
[2]) from Intel's TBB. The code from [2] probably gets much simpler
for the use case at hand because the cache size itself could be stored
as an atomic.
Regards,
Hauke
[1] http://stackoverflow.com/questions/9344739/thread-safe-lazy-creation-with-tbb
[2] https://akazarov.web.cern.ch/akazarov/cmt/releases/nightly/tbb/src/tbb/tbb_misc.h
On Fri, Jun 8, 2012 at 3:12 PM, Gael Guennebaud
<gael.guennebaud@xxxxxxxxx> wrote:
Hi,
I'm looking for some help on understanding how the following piece of
code in Eigen can lead to a race condition when the function
manage_caching_sizes is called from different threads:
inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a,
std::ptrdiff_t b)
{
return a<=0 ? b : a;
}
inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0,
std::ptrdiff_t* l2=0)
{
static std::ptrdiff_t m_l1CacheSize =
manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024);
static std::ptrdiff_t m_l2CacheSize =
manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024);
...
}
During it's first call, this function computes and store the cache sizes.
I would like to find a solution that avoids making the static variable
"thread private" as suggested there:
http://stackoverflow.com/questions/8828466/using-openmp-and-eigen-causes-infinite-loop-deadlock/10540025
The problem with this approach, is that the cache-sizes are recomputed
for every thread.
thanks,
Gaël