1

所以,这就是问题所在。我想在 CUDA 中进行计算,其中我有一个大的一维数组(代表一个晶格),我将它划分为长度为#part 的子数组,并且我希望每个线程对每个子数组进行几次计算。

更具体地说,假设我们有许多线程#threads 和许多块#blocks。该数组的大小为 N = 2 * #part * #threads * #blocks。如果我们将子数组从 1 编号到 2*#blocks*#threads,我们希望首先使用 #threads*#blocks 线程对偶数子数组进行计算,然后使用相同数量的线程对子数组进行计算具有奇数的子数组。

我认为我可以在每个线程中都有一个本地索引,它表示它的子数组将从哪里开始。

所以,我使用了以下索引:

localIndex = #part * (2 * threadIdx.x + var) + 2 * #part  * #Nthreads * blockIdx.x;

var 是 1 或 0,取决于我们是否想让线程在具有偶数或奇数的子数组上进行计算。

我尝试运行它,但当我使用多个块时似乎出现问题。我在索引方面做错了吗?

谢谢。

4

2 回答 2

1

为什么线程首先共同执行偶数,然后是奇数子数组很重要,因为不能保证块和线程执行顺序没有任何好处?

假设您仅使用 x-dimension 为您的内核维度设置建立索引:

subArrayIndexEven = 2 * (blockIdx.x * blockDim.x + threadIdx.x) * part  
subArrayIndexOdd = subArrayIndexEven + part

证明:

BLOCK_SIZE = 3
NUM_OF_BLOCKS = 2
部分 = 4

N = 2 * 3 * 2 * 4 = 48

T(threadIdx.x, blockIdx.x)
T(0, 1) -> 偶数 = 2 * (1 * 3 + 0) * 4 = 24, 奇数 = 28
T(1, 1) -> 偶数 = 2 * ( 1 * 3 + 1) * 4 = 32,奇数 = 36
T(2, 1) -> 偶数 = 2 * (1 * 3 + 2) * 4 = 40,奇数 = 44

于 2012-04-16T22:49:18.683 回答
1
idx = threads_per_block*blockIdx.x + threadIdx.x;
int my_even_offset, my_odd_offset, my_even_idx, my_odd_idx;

int my_offset = floor(float(idx)/float(num_part)); 
my_even_offset = 2*my_offset*num_part;
my_odd_offset = (2*my_offset+1)*num_part;

my_even_idx = idx + my_even_offset;
my_odd_idx  = idx + my_odd_offset;

//Do stuff with the indices.
于 2012-04-16T22:52:57.480 回答