假设我在一个 CUDA 块中有一个完整的线程扭曲,并且这些线程中的每一个都旨在与驻留在共享内存中的 T 类型的 N 个元素一起工作(所以我们总共有 warp_size * N = 32 N 个元素)。不同的线程从不访问彼此的数据。(嗯,他们这样做,但在稍后阶段,我们在这里不关心)。此访问将在循环中发生,如下所示:
for(int i = 0; i < big_number; i++) {
auto thread_idx = determine_thread_index_into_its_own_array();
T value = calculate_value();
write_to_own_shmem(thread_idx, value);
}
现在,不同的线程可能每个都有不同的索引,或者相同 - 我不会以这种或那种方式做出任何假设。但我确实想尽量减少共享内存库冲突。
如果sizeof(T) == 4
,那么这很容易:只需将线程 i 的所有数据放在共享内存地址 i、32+i、64+i、96+i 等中。这会将 i 的所有数据放在同一个 bank 中,这也是不同的从另一条车道的银行。伟大的。
但是现在——如果sizeof(T) == 8
呢?我应该如何放置和访问我的数据,以尽量减少银行冲突(对指数一无所知)?
注意:假设 T 是普通旧数据。如果这使您的答案更简单,您甚至可以假设它是一个数字。