CUDA C 程序运行的时候, by default, 由于Windows 系统假设我们的显卡(GPU) 的用途是用于图形处理的(graphics processing)。 在图形处理这种applications 中, GPU的计算的速度是十分快的。 从CPU请求GPU处理 到GPU处理完成并返回结果可能只是需要花费几个nano seconds 即可。 所以这种情况下面, 我们并需要修改注册表(registry)。 但是gpu 的driver 每2秒(默认时间)在检测到我们的GPU是hanging的时候, 驱动程序会进行复位(reset)。 也就是说, 如果我们的GPU在执行某个任务花费超过了2s, 就会出现问题。 2秒对于处理graphics 是很好的。 但是当我们使用CUDA进行一般的computation 的时候, 却很容易超过2秒。 所以我们就需要修改注册表(regestry)。
(1)什么是注册表
即把所有的计算机硬件、软件信息集中在一个称为“注册表”数据文件中,通过它来对计算机的硬软件系统进行有效的管理。打开它的方法:可以在“运行”中通过命令来打开它。命令为:regedit
(2)在修改注册表之前最好进行备份(back up), 以免在出现错误的时候,便于 restore(直接双击导入的文件就可导入到注册表)。 须知, registry is a dangerous place, 轻易不要改动。 改动的时候, 为了保险, 一定要备份。 下面我们将注册表备份到桌面上。
2.1 开始-----》 运行 ----》 regedit 打开注册表编辑器
2,2 文件 ----》 导出 ------》 桌面(这里我们保存到桌面) ----》 命名: myReg -----> 保存
(3)修改显卡驱动注册子项值
目录: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control\GraphicsDrivers
在这里我们将添加两个Dword 的 value 到这个subkey。
注意:
3,1 TdrLevel: timeout detection and recovery level.
0: off, donnot detect timeout
3: timed, this is default, it will use the value of TdrDelay(默认值为2秒)
在编辑菜单上单击新建TdrLevel, TdrDalay:设定值如下
TdrLevel: 0
TdrDelay: 20(表明设定默认值为20秒)
关闭即可保存。 接下来, 我们就可以使用GPU处理超过2秒才能完成的任务而不会出现显示驱动停止响应并恢复等错误了。
例如, 下面的程序就可以运行(时间会超过两秒了)了。
#include <iostream>
#include <cuda.h>
using namespace std;
__global__ void AddInts(int* a, int* b) {
// this could be any operation that takes more than 2 seconds
// Here I've rather pointlessly asked a single cuda thread to add b to a 10, 000, 005 times
for (int i = 0; i < 10000005; i++) {
a[0] += b[0];
}
}
int main() {
int h_a = 0; h_b = 1; // two integer variables
int* d_a;
int* d_b;
// allocate space for copies of the integers on the GPU
if(cudaMalloc((void**)&d_a, sizeof(int)) != cudaSuccess) {
cout << "Error allocating memory" << endl;
return 0;
}
if(cudaMalloc((void**)&h_b, sizeof(int)) != cudaSuccess) {
cout << "Error allocating memory" << endl;
cudaFree(d_a);
return 0;
}
// copy the integer's values from the CPU to GPU
if(codaMemcpy(d_a, &h_a, sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess) {
cout << "Error copying memory" << endl;
cudaFree(d_a);
cudaFree(d_b);
return 0;
}
if(codaMemcpy(d_b, &h_b, sizeof(int), cudaMemcpyHostToDevice) != cudaSuccess) {
cout << "Error copying memory" << endl;
cudaFree(d_a);
cudaFree(d_b);
return 0;
}
AddInts<<<1, 1>>>(d_a, d_bh);
if(codaMemcpy(&h_a, d_b, sizeof(int), cudaMemcpyDeviceToHost) != cudaSuccess) {
cout << "Error copying memory" << endl;
cudaFree(d_a);
cudaFree(d_b);
return 0;
}
cout << "Adding 1 to 10, 000, 005 times is " << h_a << endl;
cudaFree(d_a);
cudaFree(d_b);
cudaDeviceReset();
return 0;
}