我试图做的是修改驻留在映射内存中的变量,该变量会导致主程序退出。
但是主程序在s3getfile /path/to/file | vsql -h host -U user -w password -c 'COPY mytable FROM STDIN'
行继续旋转,而不是这个。我不知道如何刷新新值,因此它也可以在主机端看到。
顺便说一下。该变量在任何地方都被声明为while (var == 0) ;
,我尝试使用volatile
函数但没有成功。
主持人 - >设备方向运作良好。
系统:Windows 7 x64,驱动程序358.50,GTX 560
以下是我无法使用的代码:
__threadfence_system()
答案 0 :(得分:4)
当我在linux上运行你的代码时,它会按原样运行。
但是在Windows上,WDDM命令批处理存在问题。实际上,在您进入挂起的while循环之前,您的内核无法启动并且未启动。
WDDM命令队列是最终将发送到GPU设备的命令队列。各种事件将导致此队列被刷新"以"批次"对GPU的命令。
各种cuda运行时API调用可以有效地强制执行"刷新"命令队列的名称,例如cudaDeviceSynchronize()
或cudaMemcpy()
。但是,在内核启动之后,您不会在进入while循环之前发出任何运行时API调用。结果,在这种情况下,似乎内核调用正在“卡住”#34;在队列中,从不"刷新"。
您可以通过多种方式解决此问题,例如,在启动内核后记录事件,然后查询该事件的状态。这将具有刷新队列的效果,这将启动内核。
以下是对我有用的代码示例修改:
#include <stdio.h>
static void handleCUDAError(cudaError_t err, const char *file, int line)
{
if (err != cudaSuccess) {
printf("%s in %s at line %d\n", cudaGetErrorString(err), file, line);
exit(EXIT_FAILURE);
}
}
#define CUDA_ERROR_CHECK(err) (handleCUDAError(err, __FILE__, __LINE__ ))
__global__ void echoKernel(volatile int* semaphore)
{
*semaphore = 1;
__threadfence_system();
}
int main()
{
CUDA_ERROR_CHECK(cudaSetDevice(0));
CUDA_ERROR_CHECK(cudaSetDeviceFlags(cudaDeviceMapHost));
volatile int var = 0;
volatile int *devptr;
CUDA_ERROR_CHECK(cudaHostRegister((int*)&var, sizeof(int), cudaHostRegisterMapped));
CUDA_ERROR_CHECK(cudaHostGetDevicePointer(&devptr, (int*)&var, 0));
cudaEvent_t my_event;
CUDA_ERROR_CHECK(cudaEventCreate(&my_event));
echoKernel << < 1, 1 >> > (devptr);
CUDA_ERROR_CHECK(cudaEventRecord(my_event));
cudaEventQuery(my_event);
while (var == 0);
CUDA_ERROR_CHECK(cudaDeviceSynchronize());
CUDA_ERROR_CHECK(cudaHostUnregister((int*)&var));
CUDA_ERROR_CHECK(cudaDeviceReset());
return 0;
}
在CUDA 7.5,驱动程序358.50,Win7 x64发布项目,GTX460M上进行了测试。
请注意,我们不会在标准错误检查程序中包含cudaEventQuery
调用,因为它的预期行为是在事件尚未完成时返回非零状态。