openMP增量在线程之间添加int?
Posted
技术标签:
【中文标题】openMP增量在线程之间添加int?【英文标题】:openMP increment add int among threads? 【发布时间】:2018-02-09 00:13:13 【问题描述】:喂
我正在尝试对下面的函数进行多线程处理。我无法让计数器在 OpenMP 线程之间正确共享,我尝试了 atomic 和 int,atomic 似乎不起作用,INT 也没有。不确定,我迷路了,我该如何解决?
std::vector<myStruct> _myData(100);
int counter;
counter =0
int index;
#pragma omp parallel for private(index)
for (index = 0; index < 500; ++index)
if (data[index].type == "xx")
myStruct s;
s.innerData = data[index].rawData
processDataA(s); // processDataA(myStruct &data)
processDataB(s);
_myData[counter++] = s; // each thread should have unique int not going over 100 of initially allocated items in _myData
编辑。更新错误的语法/缺失的部分
【问题讨论】:
您选择将索引设为私有是否有特殊原因? 不编译。inxed
应该是 index
吗?请发帖minimal reproducible example
这似乎是解释为什么需要关键部分的典型示例。顺便说一句,不初始化就使用counter
是不好的。
您需要更清楚地描述预期的行为是什么以及似乎不起作用意味着什么。特别是,_myData
中的结果必须是确定性排序的吗?另外,myStruct
是什么,processDataA,B
有多贵。了解这一点对于提供具有合理性能的建议至关重要。
@MikeCAT 如果数据竞争只涉及counter
,我更喜欢使用原子操作而不是关键部分。即int temp; #pragma omp atomic capture temp = counter++; _myData[temp] = s;
.
【参考方案1】:
如果你不能使用 OpenMP atomic capture
,我会尝试:
std::vector<myStruct> _myData(100);
int counter = 0;
#pragma omp parallel for schedule(dynamic)
for (int index = 0; index < 500; ++index)
if (data[index].type == "xx")
myStruct s;
s.innerData = data[index].rawData
processDataA(s);
processDataB(s);
int temp;
#pragma omp critical
temp = counter++;
assert(temp < _myData.size());
_myData[temp] = s;
或者:
#pragma omp parallel for schedule(dynamic,c)
并试验块大小c
。
但是,原子可能比关键部分更有效。你的编译器应该支持某种形式的原子。
请注意,您的解决方案有点脆弱,因为它仅在循环内的条件评估为 true
小于 101x 时才有效。这就是我在代码中添加断言的原因。也许是更好的解决方案:
std::vector<myStruct> _myData;
size_t size = 0;
#pragma omp parallel for reduction(+,size)
for (int index = 0; index < data.size(); ++index)
if (data[index].type == "xx") size++;
v.resize(size);
...
那么,你不需要关心向量的大小,也不会浪费内存空间。
【讨论】:
以上是关于openMP增量在线程之间添加int?的主要内容,如果未能解决你的问题,请参考以下文章