C++ OpenACC中是否有更快的argmin/argmax实现?

C++ OpenACC中是否有更快的argmin/argmax实现?,c++,optimization,openacc,argmax,C++,Optimization,Openacc,Argmax,在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(minV

在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;
        }
    }
float minVal=std::numeric_limits::max();
#pragma acc并行环路缩减(最小值:最小值)
for(int i=0;i

事实上,这成为了我当前项目的瓶颈。

我们收到了minloc/maxloc的请求,但这很困难,很可能无法执行,因此没有添加任何内容。您使用的方法是推荐的解决方案。

请注意,如果
minval
在数组中多次出现,则您的代码包含竞争条件。@JérômeRichard True,但这在应用程序中是否重要?换句话说,在
minIndex=i
上方是否应该有
#pragma acc原子写入
?或者,您的意思是,使用多个相等的
minVal
s,结果是不确定的?在大多数应用程序中,后者不重要。首先,结果可能是不确定的,而我在您的应用程序中可能不是问题。也就是说,是的,我认为至少进行一次原子写入对于避免由于竞争条件而产生与硬件相关的奇怪效果是很重要的。事实上,虽然我不应该成为大多数GPU的关键问题,但没有任何东西可以阻止某些GPU以非原子方式写入
minIndex
,从而导致错误的结果。请注意,我认为大多数主流现代GPU都以原子方式写入4字节的值,因此在实践中不应该出现这种效果。您可以使用原子最小值/最大值获得确定性结果。在这里,大多数GPU上的计算可能会受到内存限制。即使是非常糟糕的minloc/maxloc实现,只要实现可以扩展,在许多GPU上也会更快。可以搜索每个块的minloc/maxloc,然后使用原子CA执行块之间的缩减。或者,可以对旧的/无功能的GPU执行两次减少。由此产生的实现在这里可以快2倍(并且可能会在许多现代GPU上实现)。@JérômeRichard您能在回答中用一些代码概括一下您的建议吗?这对我来说将是一个巨大的帮助。@Dunkelkoon注意,我正在谈论一个可能的后端(部分)实现。因此,不是OpenACC代码,而是类似Cuda的代码(我想OpenCL也可以实现同样的功能,但我非常熟悉它)。这对你合适吗?@JérômeRichard啊,我的错。谢谢你澄清这一点。