这个内核正在做正确的事情,给我正确的结果。如果我想提高性能,我的问题更多的是while循环的正确性。我尝试了几种块和线程的配置但是如果我要更改它们,while循环将不会给我正确的结果。 我改变内核配置的结果是firstArray和secondArray不会被完全填充(它们在单元格内部会有0)。必须使用从 if循环获得的curValue填充两个数组。
欢迎任何建议:)
提前谢谢
#define N 65536
__global__ void whileLoop(int* firstArray_device, int* secondArray_device)
{
int curValue = 0;
int curIndex = 1;
int i = (threadIdx.x)+2;
while(i < N) {
if (i % curIndex == 0) {
curValue = curValue + curIndex;
curIndex *= 2;
}
firstArray_device[i] = curValue;
secondArray_device[i] = curValue;
i += blockDim.x * gridDim.x;
}
}
int main(){
firstArray_host[0] = 0;
firstArray_host[1] = 1;
secondArray_host[0] = 0;
secondArray_host[1] = 1;
// memory allocation + copy on GPU
// definition number of blocks and threads
dim3 dimBlock(1, 1);
dim3 dimGrid(1, 1);
whileLoop<<<dimGrid, dimBlock>>>(firstArray_device, secondArray_device);
// copy back to CPU + free memory
}
答案 0 :(得分:3)
这里存在数据依赖性问题,这会阻碍您进行一些有意义的优化。变量curValue和curIndex在while循环中更改并前馈到下一次运行。只要您尝试优化循环,您就会发现在这些变量具有不同状态并且结果发生变化的情况下。
我真的不知道你试图实现什么,但是尝试使while循环不受前一次循环运行的值的影响,以避免依赖。尝试将数据分成线程和数据块,以便在环境状态(如threadIdx,blockDim,gridDim ......)上计算indizes和值。
还尝试避免条件循环。最好使用具有恒定运行次数的循环。这也更容易优化。
答案 1 :(得分:1)
一些事情:
目前,从平行的角度来看,此代码存在两个主要问题:
int i = (threadIdx.x)+2;
...为a生成2
的起始索引
单线程;对于单个块中的两个线程,2
和3
,依此类推。我怀疑这是
您想要的前两个位置(0
,1
)永远不会得到
解决。 (请记住,数组从C中的索引0
开始。)
此外,如果您包含多个块(比如2个块)
每个都有一个线程)然后你会有多个重复的索引
(例如,对于2 b x 1 t - >索引b1t1:2
,b1t2:2
),当您使用索引时
写入全局内存会产生冲突和错误。执行int i = threadIdx.x + blockDim.x * blockIdx.x;
之类的操作将是正确计算索引的典型方法,以避免出现此问题。
您
最终表达式i += blockDim.x * gridDim.x;
没问题,因为它
为i添加一个等于线程总数的数字
不会造成额外的冲突或重叠。
如果您愿意,可以解决问题1和问题2,但除此之外,请考虑您的总体目标以及您尝试优化的算法类型,并提出更加并行友好的解决方案 - 或者考虑GPU计算是否真的使用感觉你的问题。
答案 2 :(得分:1)
要并行化此算法,您需要提供一个公式,该公式可以直接计算数组中给定索引的值。因此,选择数组范围内的随机索引,然后考虑确定该位置的值的因素。找到公式后,通过将随机索引的输出值与串行算法中的计算值进行比较来测试它。如果这是正确的,那么创建一个内核,通过根据它的线程和块索引选择唯一索引来开始。然后计算该索引的值并将其存储在数组中的相应索引中。
一个简单的例子:
串行:
__global__ void serial(int* array)
{
int j(0);
for (int i(0); i < 1024; ++i) {
array[i] = j;
j += 5;
}
int main() {
dim3 dimBlock(1);
dim3 dimGrid(1);
serial<<<dimGrid, dimBlock>>>(array);
}
并行:
__global__ void parallel(int* array)
{
int i(threadIdx.x + blockDim.x * blockIdx.x);
int j(i * 5);
array[i] = j;
}
int main(){
dim3 dimBlock(256);
dim3 dimGrid(1024 / 256);
parallel<<<dimGrid, dimBlock>>>(array);
}