并行填充向量,顺序不重要
Populating a vector in parallel, order not important
我必须创建一个包含 k 个元素的向量。每个线程都将创建它的部分,比方说 k * 25%,并且必须将它放入向量中的任何索引处。受到这个example的驱使,我正准备做这样的事情:
std::atomic<std::vector<aClass<templatedType>>> H;
但这行不通:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/atomic:823:13: error:
_Atomic cannot be applied to type
'std::__1::vector<StableHashFunction<int>,
std::__1::allocator<StableHashFunction<int> > >' which is not trivially
copyable
mutable _Atomic(_Tp) __a_;
因为它不可简单复制 - 并且解决方法也不是很好。而且,我需要它是原子的吗?
问题来了,当我不关心顺序的时候,我还用atomic吗?换句话说,数据竞争是否只影响元素的顺序,或者它们会导致其他副作用,比如躲避一个元素(所以不是 k 个元素,最后只有 k - 1 个)?
如果您想将原子与矢量或另一个一起使用 class,您可以改用指针。我认为在你的情况下你必须使用互斥锁来使线程安全地访问向量,或者使用 TBB library 。该库具有您完成任务所需的所有功能。
当您尝试并行插入项目时,仅当向量必须更改其大小时才会出现问题:并发插入将不得不更新内存中的相同位置,从而导致不正确的行为(崩溃、丢失项目等)
但是,同时设置现有向量的不同元素不会导致问题,因此解决此问题的常见方法是预先分配向量。
此方法需要向量元素的默认构造函数,并且预先知道每个线程要放入向量中的项目的确切数量。比如你知道线程0要放置100个元素,线程1要放置120个元素,线程2要放置110个元素,你预分配一个100+120+110个元素的vector,然后为每个线程提供自己的初始索引:0、100 和 220。现在每个线程都可以将项目放入向量中,而不会 运行 出现并发问题。
我必须创建一个包含 k 个元素的向量。每个线程都将创建它的部分,比方说 k * 25%,并且必须将它放入向量中的任何索引处。受到这个example的驱使,我正准备做这样的事情:
std::atomic<std::vector<aClass<templatedType>>> H;
但这行不通:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/atomic:823:13: error:
_Atomic cannot be applied to type
'std::__1::vector<StableHashFunction<int>,
std::__1::allocator<StableHashFunction<int> > >' which is not trivially
copyable
mutable _Atomic(_Tp) __a_;
因为它不可简单复制 - 并且解决方法也不是很好。而且,我需要它是原子的吗?
问题来了,当我不关心顺序的时候,我还用atomic吗?换句话说,数据竞争是否只影响元素的顺序,或者它们会导致其他副作用,比如躲避一个元素(所以不是 k 个元素,最后只有 k - 1 个)?
如果您想将原子与矢量或另一个一起使用 class,您可以改用指针。我认为在你的情况下你必须使用互斥锁来使线程安全地访问向量,或者使用 TBB library 。该库具有您完成任务所需的所有功能。
当您尝试并行插入项目时,仅当向量必须更改其大小时才会出现问题:并发插入将不得不更新内存中的相同位置,从而导致不正确的行为(崩溃、丢失项目等)
但是,同时设置现有向量的不同元素不会导致问题,因此解决此问题的常见方法是预先分配向量。
此方法需要向量元素的默认构造函数,并且预先知道每个线程要放入向量中的项目的确切数量。比如你知道线程0要放置100个元素,线程1要放置120个元素,线程2要放置110个元素,你预分配一个100+120+110个元素的vector,然后为每个线程提供自己的初始索引:0、100 和 220。现在每个线程都可以将项目放入向量中,而不会 运行 出现并发问题。