【发布时间】:2016-03-21 07:22:32
【问题描述】:
我正在阅读"Cuda by Example" by Jason Sanders and Edward Kandrot 这本书,并且对他们使用锁来计算两个数组的点积有疑问(在链接 pdf 的第 254-258 页上找到)。他们定义了他们的 lock.h 头文件:
#ifndef __LOCK_H__
#define __LOCK_H__
struct Lock{
int *mutex;
Lock(){
int state = 0;
cudaMalloc((void**)&mutex, sizeof(int));
cudaMemcpy(mutex, &state, sizeof(int), cudaMemcpyHostToDevice);
}
~Lock(){
cudaFree(mutex);
}
__device__ void lock(){
while (atomicCAS(mutex, 0 ,1) != 0);
}
__device__ void unlock(){
atomicExch(mutex, 0);
}
};
#endif
然后他们将他们的点积内核称为:
int main()
{
// bunch of code, initialization etc
Lock lock;
dot<<<blocksPerGrid,threadsPerBlock>>>(lock, dev_a, dev_b, dev_c);
// more code, frees, etc
}
点内核声明为:
__global__ void dot(Lock lock, float *a, float *b, float *c);
这不会因为 Lock 结构不包含复制构造函数而创建一个无效的空闲吗?我们按值传递锁,它只是按值复制互斥指针。当我们退出内核时,析构函数在这个互斥指针上调用 cudaFree。当我们退出主函数时,我想再次调用析构函数,但现在互斥锁已经被释放了!我问是因为在不同的较大代码中,当使用相同的想法时,我会遇到 cudeErrorInvalidDevicePointer 错误,我认为问题在于没有复制构造函数。
【问题讨论】:
-
当然,但我的问题是缺少复制构造函数是否是问题所在。记住这段代码不是我的。这是链接已出版书籍中的一个示例,我基本上是在询问他们是否因不包括复制构造函数而出错。