Re: [eigen] Help on solving a race condition |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Help on solving a race condition
- From: Gael Guennebaud <gael.guennebaud@xxxxxxxxx>
- Date: Fri, 8 Jun 2012 16:25:02 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:content-transfer-encoding; bh=o6RXOOoc1rds65cj673ecLh1xGfaOXPA46o9EZzQCs8=; b=A9Bsa5mcdrdRXJ6p0evFJBQJuvoli6/605gGyYclQqsQ9NgSIjKJ00pJzYwnGegSHJ vScjGn3kvbj7VU0hRD0jIkhT32OamEQoKEjdtncG/1KFM0fNkfkFJCHrxpCayj8Machq aGfdj/wWGU1OCz5orba6C23x0d0oCgOc5zQaIoSf4AavluqP43Bn5KK2xNQoBFeVYYW3 scMsNiZGLEKtW4VCQ8EaEm+OqMSWn8pv2tbMtOJarr3QoPP9lVsfaoB8wI13PZ3P4AeZ IZ9bk5lXyk8OSNPxJYtFsX2cGPpO3THfKCn9e8GHt2ZNpiWsqzb2jjxSzABp3tuLrH0F qqog==
Yes I've though about the possibility to request users to call a
Eigen::init() function at their program startup, but that's not very
convenient.
Such an init function could be automatically called by adding a global
static variable in one of Eigen's header:
static bool static_init = init();
The consequence is that the init() function will be called for every
compilation unit (every cpp file including Eigen). Even though only
the first call would really perform something, that's pretty ugly.
I also tried the following variant:
static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;
static bool initialized = false;
if(!initialized)
{
m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024);
m_l2CacheSize =
manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024);
initialized = true;
}
Unless the compiler change the execution order, in this case I don't
see how m_l1CacheSize could be used without being initialized. In the
worst case they will be computed by different twice, but we expect
them to return the same value anyway.
Though, helgrind is still complaining about the risk of a race-condition.
thanks,
gael
On Fri, Jun 8, 2012 at 3:57 PM, Brad Bell <bradbell@xxxxxxxxxx> wrote:
> CppAD uses the following approach:
>
> Single threaded code does not need to do anything special, but
> multi-threaded code needs to do extra things (like initialize static
> variables) and there are special routines to help do so. See
> http://www.coin-or.org/CppAD/Doc/multi_thread.xml
> and
>
> https://projects.coin-or.org/CppAD/browser/trunk/cppad/local/parallel_ad.hpp
>
>
>
> On 06/08/2012 06:12 AM, Gael Guennebaud 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
>>
>>
>>
>
>
>