我最近开始学习CUDA,并且已经使用Nsight将我的CUDA集成到MS Visual Studio 2010中。我还获得了“CUDA by example”这本书,我将通过所有的例子并编译它们。然而,我遇到了一个错误,我不明白。 该程序来自第4章,它是julia_gpu的例子。原始代码:
#include "../common/book.h"
#include "../common/cpu_bitmap.h"
#define DIM 1000
struct cuComplex {
float r;
float i;
cuComplex( float a, float b ) : r(a), i(b) {}
__device__ float magnitude2( void ) {
return r * r + i * i;
}
__device__ cuComplex operator*(const cuComplex& a) {
return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
}
__device__ cuComplex operator+(const cuComplex& a) {
return cuComplex(r+a.r, i+a.i);
}
};
__device__ int julia( int x, int y ) {
const float scale = 1.5;
float jx = scale * (float)(DIM/2 - x)/(DIM/2);
float jy = scale * (float)(DIM/2 - y)/(DIM/2);
cuComplex c(-0.8, 0.156);
cuComplex a(jx, jy);
int i = 0;
for (i=0; i<200; i++) {
a = a * a + c;
if (a.magnitude2() > 1000)
return 0;
}
return 1;
}
__global__ void kernel( unsigned char *ptr ) {
// map from blockIdx to pixel position
int x = blockIdx.x;
int y = blockIdx.y;
int offset = x + y * gridDim.x;
// now calculate the value at that position
int juliaValue = julia( x, y );
ptr[offset*4 + 0] = 255 * juliaValue;
ptr[offset*4 + 1] = 0;
ptr[offset*4 + 2] = 0;
ptr[offset*4 + 3] = 255;
}
// globals needed by the update routine
struct DataBlock {
unsigned char *dev_bitmap;
};
int main( void ) {
DataBlock data;
CPUBitmap bitmap( DIM, DIM, &data );
unsigned char *dev_bitmap;
HANDLE_ERROR( cudaMalloc( (void**)&dev_bitmap, bitmap.image_size() ) );
data.dev_bitmap = dev_bitmap;
dim3 grid(DIM,DIM);
kernel<<<grid,1>>>( dev_bitmap );
HANDLE_ERROR( cudaMemcpy( bitmap.get_ptr(), dev_bitmap,
bitmap.image_size(),
cudaMemcpyDeviceToHost ) );
HANDLE_ERROR( cudaFree( dev_bitmap ) );
bitmap.display_and_exit();
}
我的Visual Studio强迫我将cuComplex构造函数强制为 device ,否则它将无法编译(它告诉我以后不能在julia函数中使用它),我认为这是公平的足够。所以我有:
__device__ cuComplex( float a, float b ) : r(a), i(b) {}
但是当我运行这个例子时(已经添加了必要的包含它来运行VS,这是cuda_runtime.h和device_launch_parameters.h,以及将glut32.dll复制到与exe相同的文件夹中)它快速失败,杀死我的设备驱动程序并说这是由于第94行中的未知错误,这是主要的cudaMemcpy调用。确切地说,它是包含调用“cudaDeviceToHost”的实际行。坦率地说,我已尝试逐行创建一些断点,并且驱动程序在内核调用时死亡。
有人可以告诉我可能有什么问题吗?我是CUDA的菜鸟,并且不知道为什么一个简单的例子会像这样自杀。我能做错什么?坦率地说,我甚至不知道该调查什么。 我有CUDA 4.1工具包,NSight 2.1和GeForce GT445M,计算能力分别为2.1和295版本的驱动程序。
答案 0 :(得分:2)
我还没来得及测试这个,但我认为就Windows而言,它可能是你的GFX“超时”。
Windows具有Vista的默认行为,告诉gfx驱动程序在2秒后恢复。如果你的工作需要更长时间,那么你就会被启动。您可以通过注册表增加或删除此功能。我假设您需要重新启动,因为我刚刚进行了更改,但它还没有运行。 有关详细信息,请参阅此链 http://msdn.microsoft.com/en-us/windows/hardware/gg487368.aspx
...
超时检测和恢复:Windows Vista尝试检测这些 有问题的挂起情况并恢复响应式桌面 动态。在此过程中,Windows显示驱动程序模型(WDDM) 驱动程序重新初始化并重置GPU。无需重启, 这极大地增强了用户体验。唯一可见的神器 从挂起检测到恢复是屏幕闪烁,其中 重置图形堆栈的某些部分导致a 屏幕重绘。某些较旧的Microsoft DirectX应用程序可能会呈现给 在这次恢复结束时出现黑屏。最终用户必须 重启这些应用程序以下是对该的简要概述 TDR流程:....
显然,这就是为什么它是一个奇怪的错误,因为它会根据gfx的速度为不同的人提供不同比例的mem copy错误。
这是CUDA中的一个已知问题。
答案 1 :(得分:0)
您可以尝试更改此内容: const float scale = 1.5;
更大的东西,如3.5,4.5,5.5。
例如: const float scale = 5.5;