目前正在尝试使用CUDA中的减少#3大纲pdf here。
以下是我的缩减功能的外观
template <typename T>
__device__ void offsetReduction(planet<T> *bodies, T *outdata, int arrayIdent, int nbodies){
extern __shared__ T sdata[];
unsigned int tID = threadIdx.x;
unsigned int i = tID + blockIdx.x * blockDim.x;
if (arrayIdent == 1){
if (i < nbodies){
sdata[tID] = bodies[i].vx * bodies[i].mass;
}
__syncthreads();
}
if (arrayIdent == 2){
if (i < nbodies){
sdata[tID] = (bodies[i].vy * bodies[i].mass);
}
__syncthreads();
}
if (arrayIdent == 3){
if (i < nbodies){
sdata[tID] = (bodies[i].vz * bodies[i].mass);
}
__syncthreads();
}
for (unsigned int stride = blockDim.x / 2; stride > 0; stride >>=1)
{
if (tID < stride)
{
sdata[tID] += sdata[tID + stride];
}
__syncthreads();
}
if (tID == 0)
{
outdata[blockIdx.x] = sdata[0];
}
然而,它似乎没有正常工作,所以我做了一些计算。
我启动了相同数量的线程和&#39; int nbodies&#39;,在我的情况下我选择了5.所以5个线程中的每一个都进来并为sdata []添加一个值没问题。然而,一旦它到达添加部分就会出错。
在第一次迭代中,线程0访问sdata [3],线程1访问sdata [4],其他线程不执行任何操作。在第二次迭代中,线程0访问sdata 1,其他线程不执行任何操作。然后,添加完成&#39;并且内核完成。但是sdata [2]永远不会被添加,所以我得到一个不正确的值存储在sdata [0]。
我错过了一些非常明显的东西吗? (我一直盯着这个,所以我可能有。
答案 0 :(得分:1)
这个减少代码,就像任何其他&#34;树状&#34;减少操作,要求参与共享内存减少的线程数等于2的幂才能正常工作。
请注意,这意味着可以设计一个还原内核,该内核可以为每个块的2个线程的任何多个正确运行,具有最近的2个线程的较小功率执行实际减少。但是,您发布的代码不能像那样工作。