【发布时间】:2016-08-11 17:41:50
【问题描述】:
我在写一个n体模拟,基本上整个操作是:
-Prepare CUDA memory
loop {
-Copy data to CUDA
-Launch kernel
-Copy data to host
-Operations using data (drawing etc.)
}
我注意到几乎 90% 的时间都花在了将数据写入内核中的全局设备内存上。这是内核:
__global__ void calculateForcesCuda(float *deviceXpos, float *deviceYpos, float *deviceZpos,
float *deviceXforces, float *deviceYforces, float *deviceZforces,
float *deviceMasses, int particlesNumber) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid <= particlesNumber) {
float particleXpos = deviceXpos[tid];
float particleYpos = deviceYpos[tid];
float particleZpos = deviceZpos[tid];
float xForce = 0.0f;
float yForce = 0.0f;
float zForce = 0.0f;
for (int index=0; index<particlesNumber; index++) {
if (tid != index) {
float otherXpos = deviceXpos[index];
float otherYpos = deviceYpos[index];
float otherZpos = deviceZpos[index];
float mass = deviceMasses[index];
float distx = particleXpos - otherXpos;
float disty = particleYpos - otherYpos;
float distz = particleZpos - otherZpos;
float distance = sqrt((distx*distx + disty*disty + distz*distz) + 0.01f);
xForce += 10.0f * mass / distance * (otherXpos - particleXpos);
yForce += 10.0f * mass / distance * (otherYpos - particleYpos);
zForce += 10.0f * mass / distance * (otherZpos - particleZpos);
}
}
deviceXforces[tid] += xForce;
deviceYforces[tid] += yForce;
deviceZforces[tid] += zForce;
}
}
运行它的设备是 GTX 970。执行时间约为 8.0 秒,但添加这些标志后:-gencode arch=compute_52,code=sm_52 strong>,性能提升到 6.7 秒左右。注释掉写入全局设备内存的代码后:
deviceXforces[tid] += xForce;
deviceYforces[tid] += yForce;
deviceZforces[tid] += zForce;
... 总执行时间减少到 0.92 秒左右,这意味着写入全局设备内存大约需要 86% 的执行时间。有没有办法提高这些写入的性能?
【问题讨论】:
-
您误解了正在发生的事情。内存写入不是此代码中的瓶颈。删除它们只是让编译器优化你的大部分代码
-
@talonmies 上帝,你说得对。所以计算本身实际上很慢。我会留下这个问题,以防其他人犯同样的错误。
-
我怀疑计算是问题所在。循环内的内存负载将是最大的问题。开始考虑数据重用和缓存性能
-
正如 talonmies 所说,代码可能受内存限制。但是,附带说明一下:在性能方面,此代码中执行的计算将受益于
rnorm3d()函数的使用。