我在多个GPU上运行高性能计算(每台机器有两个GPU),目前我在GeForce GTX TITAN上测试我的代码。最近我注意到随机内存错误发生,导致我不能再依赖结果。尝试调试并遇到了我不理解的问题。如果有人能帮我理解以下情况发生的原因,我将不胜感激。
所以,这是我的GPU:
$ nvidia-smi -a
Driver Version : 331.67
GPU 0000:03:00.0
Product Name : GeForce GTX TITAN
...
VBIOS Version : 80.10.2C.00.02
FB Memory Usage
Total : 6143 MiB
Used : 14 MiB
Free : 6129 MiB
Ecc Mode
Current : N/A
Pending : N/A
我使用的 Linux 机器 (Ubuntu 12.04 64 位系统):
$ uname -a
Linux cluster-cn-211 3.2.0-61-generic #93-Ubuntu SMP Fri May 2 21:31:50 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
这是我的代码(基本上,分配4G内存,填充为零,复制回主机并检查所有值是否为零;剧透:它们不是)
#include <cstdio>
#define check(e) {if (e != cudaSuccess) { \
printf("%d: %s\n", e, cudaGetErrorString(e)); \
return 1; }}
int main() {
size_t num = 1024*1024*1024; // 1 billion elements
size_t size = num * sizeof(float); // 4 GB of memory
float *dp;
float *p = new float[num];
cudaError_t e;
e = cudaMalloc((void**)&dp, size); // allocate
check(e);
e = cudaMemset(dp, 0, size); // set to zero
check(e);
e = cudaMemcpy(p, dp, size, cudaMemcpyDeviceToHost); // copy back
check(e);
for(size_t i=0; i<num; i++) {
if (p[i] != 0) // this should never happen, amiright?
printf("%lu %f\n", i, p[i]);
}
return 0;
}
我这样运行它。
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2013 NVIDIA Corporation
Built on Sat_Jan_25_17:33:19_PST_2014
Cuda compilation tools, release 6.0, V6.0.1
$ nvcc test.cu
nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
$ ./a.out | head
516836128 -0.000214
516836164 -0.841684
516836328 -3272.289062
516836428 -644673853950867887966360388719607808.000000
516836692 0.000005
516850472 232680927002624.000000
516850508 909806289566040064.000000
...
$ echo $?
0
这不是我期望的结果:许多元素都是非零值。以下是一些观察结果:
- 我使用
cuda-memcheck
进行了检查,没有错误。通过valgrind
的memcheck
也没有错误。 - 内存分配正常工作,
nvidia-smi
报告4179MiB / 6143MiB
- 如果我
- 分配较少的内存(例如2 GB)
- 使用
-arch sm_30
或-arch compute_30
进行编译(参见capabilities) - 从SDK版本6.0回到5.5
- 从 GTX Titan 更改为 Tesla K20c(启用ECC检查且所有计数器均为零)。 结果相同,我已经在五张不同的GPU卡上进行了测试。
- 在设备上分配多个较小的数组
- 如果在GTX 680上测试,错误将消失。
p
指针是否为NULL
? - Vitality