在CUDA中执行此操作的最佳方法是什么?
...
for(int i=0;i<size;++i)
for(int j=i+1;j<size ;++j)
temp_norm+=exp((train[i]-train[j])/tau);
这是否相同?
...
int i = threadIdx.x + blockIdx.x * blockDim.x;
int j = threadIdx.y + blockIdx.y * blockDim.y;
if (i>=size || j>=size) return;
if(j>i)
temp_norm+=exp((train[i]-train[j])/tau);
非常感谢任何帮助!
答案 0 :(得分:2)
如何最好地实施真正取决于size
的大小。但假设它很大,例如1000或更多...
要按照您的建议进行操作,您需要使用atomicAdd(),如果太多线程原子地添加到同一地址,这可能会很昂贵。更好的方法可能是使用并行减少。
查看NVIDIA CUDA SDK中的"reduction"示例。
YMMV具有以下内容,因为它未经测试,我不知道您的数据大小,但这样的事情应该有效。使用该示例中的“reduction6”内核,但将计算添加到第一个while循环。将i
和gridSize
的初始化替换为
unsigned int i = blockIdx.x*blockSize + threadIdx.x;
unsigned int gridSize = blockSize * gridDim.x;
用
替换while (i < n)
循环
while (i < size)
{
for (unsigned int j = i+1; j<size; ++j)
mySum += exp((train[j]-train[i])/tau);
i += gridSize;
}
(注意,浮点运算是非关联的,因此并行实现中的不同操作顺序可能会给你一个与顺序实现略有不同的答案。由于平衡,它甚至可以给你一个稍微准确的答案树减少,取决于您的输入数据。)