I'm curious if anyone here has knowledge on the efficiency of atomics, specifically std::atomic<int>. My problem goes as follows:
I have a data set, say data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} that is passed into an algorithm algo(begin(data), end(data)). algo partitions the data into chunks and executes each chunk asynchronously, so algo would perform it's operation on, say, 4 different chunks:
{1, 2, 3}
{4, 5, 6}
{7, 8, 9}
{10, 11, 12}
in each separate partition I need to return the count of elements that satisfy a predicate op at the end of each partition
//partition lambda function
{
//'it' corresponds to the position in it's respective partition
if( op(*it) )
count++;
//return the count at the end of this partition
return count;
}
the problem is that I'm going to run into a data race just incrementing 1 variable with 4 chunks executing asynchronously. I was thinking of two possible solutions:
use a std::atomic
- the problem here is I know very little about C++'s atomics, and from what i've heard they can be inefficient. Is this true? what results should I expect to see with using atomics to keep track of a count?
use a shared array, where the size is the partition count
- I know my shared arrays pretty well so this idea doesn't seem too bad, but I'm unsure how it would hold up when a very small chunk size is given, which would make the shared array keeping track of the count at the end of each partition quite large. It would be useful however as the algorithm doesn't have to wait for anything to finish to increment, it simply places it's respective count in the shared array.
so with both my ideas, I could implement it possible as:
//partition lambda function, count is now atomic
{
//'it' corresponds to the position in it's respective partition
if( op(*it) )
count++;
//return the count at the end of this partition
return count.load();
}
//partition lambda function, count is in shared array that will be be accessed later
//instead of returned
{
int count = 0;
//'it' corresponds to the position in it's respective partition
if( op(*it) )
count++;
//total count at end of each partition. ignore fact that partition_id = 0 wouldn't work
shared_arr[partition_id] = shared_arr[partition_id - 1] + count;
}
any ideas on atomic vs shared_array?
Aucun commentaire:
Enregistrer un commentaire