通过示例点积在 Cuda 中使用锁
Use of locks in Cuda by Example dot product
我正在阅读Jason Sanders和Edward Kandrot的"Cuda by Example"一书,并对他们使用锁来计算两个数组的点积有疑问(可在链接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 错误,我认为问题是没有复制构造函数。
是的,你是对的,将进行额外的 dtor 调用 - 您也可以自己检查......
下面是一个用于验证的简单示例:
#include <iostream>
#include <cuda_runtime.h>
struct A {
A() { std::cout << "ctor for " << this << std::endl << std::flush; }
~A() { std::cout << "dtor for " << this << std::endl << std::flush; }
};
__global__ void foo(A device_a) { }
int main(void) {
A host_a;
foo<<<1,1>>>(host_a);
cudaDeviceReset();
return 0;
}
输出为:
ctor for 0x7ffe584c85bf
dtor for 0x7ffe584c85df
dtor for 0x7ffe584c85bf
因此,您将获得默认的复制 ctor;并且两个副本的构建和销毁都发生在主机上(这些是仅限主机的功能,设备没有 <iostream>
)。我实际上觉得这有点奇怪,但我想这是 CUDA 的"C-ish"起源的一部分,将内核参数视为 POD。看到 ctor 和 dtor 如何拥有__device__
和__host__
限定符,这尤其令人惊讶。
但是,在该示例中对cudaFree()
的额外调用应该不是问题(手指交叉):CUDA 运行时 API 手册第 3.9 节说调用应该失败并返回cudaErrorInvalidDevicePointer
。
尽管如此,这是糟糕的编程实践,结构应该以不同的方式编写 IMO。
- 编译时未启用intel oneApi CUDA支持
- 在cuda线程之间共享大量常量数据
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- CUDA内核和数学函数的显式命名空间
- CUDA:统一内存和指针地址的更改
- 调试 CUDA MMU 故障
- 使用 CUDA 和纹理进行图像减法
- 将 2D 推力::d evice_vector 复矩阵传递给 CUDA 内核函数
- 编译 CUDA 与数学函数的叮当
- 为什么 CUDA 不会导致C++代码加速?
- 如何防止 CUDA-GDB 中的<优化输出>值
- 通过Python Distutils(用于Python C扩展)使用可重定位的设备代码编译CUDA代码
- CUDA三角函数中的数学保证
- CUDA 使用共享内存平铺 3D 卷积实现
- CUDA:cudaMallocManage处理退出吗?
- Opencv 加速与 CUDA 在 C++.
- Cuda:具有位集数组的 XOR 单位集
- 用于构建 cuda .so 文件(共享库)的生成文件
- Cuda:访问违规写入位置0x0000000000000000