【发布时间】:2021-08-26 22:36:12
【问题描述】:
在 OpenACC 中计算 argmin 是否有比在一个最小缩减循环和另一个循环中拆分工作以实际找到最小值索引更快的替代方法?
这看起来很浪费:
float minVal = std::numeric_limits<float>::max();
#pragma acc parallel loop reduction(min: minVal)
for(int i = 0; i < arraySize; ++i) {
minVal = fmin(minVal, array[i]);
}
#pragma acc parallel loop
for(int i = 0; i < arraySize; ++i) {
if(array[i] == minVal){
minIndex = i;
}
}
事实上,这成了我当前项目的瓶颈。
【问题讨论】:
-
请注意,如果
minval在数组中出现多次,则您的代码包含竞争条件。 -
@JérômeRichard 没错,但这在应用程序中重要吗?换言之,
minIndex = i上方应该有#pragma acc atomic write吗?或者你的意思是,多个相等的minVals 的结果是不确定的?在大多数应用程序中,后者应该无关紧要,afaik。 -
首先,结果可能不是确定性的,而我在您的应用程序中可能不是问题。话虽如此,是的,我认为至少进行一次原子写入对于避免由于竞争条件而导致的与硬件相关的奇怪影响很重要。事实上,虽然我不应该成为大多数 GPU 的关键问题,但没有什么能阻止某些 GPU 以非原子方式写入
minIndex导致错误结果。请注意,我认为几乎所有主流现代 GPU 都以原子方式写入 4 字节值,因此在实践中不应出现这种效果。您可以使用原子最小值/最大值获得确定性结果。
标签: c++ optimization openacc argmax