【发布时间】:2013-11-24 14:10:37
【问题描述】:
我想在内核执行时从主机修改一块映射内存,然后从内核中读取这个值。
我正在尝试通过以下方式执行此操作。我有一个这样的内核:
__global__ void kernel(int* d_ptr)
{
*d_ptr = 1;
while( *d_ptr);
}
d_ptr 映射到主机可访问的一块内存。
我也有一个类似这样的宿主线程
void run( void* input )
{
int* h_ptr = (int*)input;
while( kernel_running)
*h_ptr = 0;
}
因此,主机线程反复向内核重复读取的位置写入 0,直到它看到 0。理论上,内核应该在读取主机线程写入的值后立即停止。问题是内核从不读取这个 0,所以它永远不会终止。
奇怪的是,如果我像这样在内核中添加打印语句
__global__ void kernel(int* d_ptr)
{
*d_ptr = 1;
while( *d_ptr) printf("%d\n", *d_ptr);
}
然后它确实读取 0 并终止。我不知道发生了什么。 cuda programming guide 没有提供很多关于并发访问映射内存的信息,而且也很难找到解决这个问题的问题。任何指针?我正在使用 Windows 并且正在编译
nvcc -g -arch=sm_20 -lineinfo
整个代码如下所示:
bool kernel_running = 0;
__global__ void kernel(int* d_ptr)
{
*d_ptr = 1;
while( *d_ptr) printf("%d\n", *d_ptr);
}
void run( void* input )
{
int* h_ptr = (int*)input;
while( kernel_running)
{
*h_ptr = 0;
}
}
int main()
{
// HOST AND DEVICE POINTERS
int* h_ptr = 0;
int* d_ptr = 0;
// INITIALIZE POINTERS
assert( cudaHostAlloc(&h_ptr, sizeof(int), cudaHostAllocMapped) == cudaSuccess);
assert( cudaHostGetDevicePointer(&d_ptr, h_ptr, 0) == cudaSuccess);
// RUN KERNEL
kernel_running = 1;
_beginthread( run, 0, h_ptr);
kernel<<<1,1>>>(d_ptr);
assert( cudaDeviceSynchronize() == cudaSuccess);
kernel_running = 0;
}
【问题讨论】: