我是 GPU 加速方面的新手。刚刚尝试了在 CUDA 上使用简单内核进行基本的 LWJGL 绑定,没有共享内存,函数签名如下
__global__ void compute(
unsigned int n,
unsigned long long int* timeMs,
double* a, double* b, double* c,
double *g_odata)
内核函数基本上是从上述数组(timeMs、a、b、c 等)中检索线程 ID 的数据并进行一些数学运算,然后将结果放入相应线程 ID 的 g_odata 数组中。n 是要计算的线程数(当然,它会检查线程 ID 是否超过 n)。没有共享内存或减少。
现在,当我测量内核完成所需的总时间时,出现了关于 n(总线程大小/并行度)和块大小的奇怪情况(我有一个带有 80 个多处理器的 GPU)
我clock64()
在内核函数前后添加了时间戳,并收集了每个线程的总时间,很明显,线程越多,执行相同任务的速度就越慢
现在的问题:
- 为什么总时间在 100 个线程之后就开始增加?考虑到 80 个多处理器和 10K+ 个 cuda 核心,我预计这个数字会更大,所以可能是某些配置问题?
- 为什么内核函数在更多线程上花费更多时间?执行是否交错(即调度程序可以在其中一个线程完成之前暂停它并执行另一个线程)
- 为什么线程达到 100 个之后会出现停滞行为?为什么它会再次起飞
- 根据块数而变化的性能。我读到网格/块只是开发人员的观点,没有影响(特别是对于没有共享/减少的完全隔离的线程)。那么为什么这很重要,以及如何选择最佳块大小?