有没有办法防止内存地址被访问?
Is there a way to prevent a memory address being accessed?
是否可以防止某个内存地址在一段时间内被其他线程访问?例如:
__global__ void func(int* a){
// other computation
__lock_address(a);
a[0] += threadIdx.x;
__unlock_address(a);
}
第一个完成 other computations
并到达 __lock_address
的线程将锁定该内存地址,直到 _unlock_address
被调用,任何其他到达 __lock_address
的线程都必须等到第一个线程解锁它。
上面的例子基本上等同于atomicAdd
,但是如果我想做更复杂的计算而不是简单的加法呢?
编辑:
mutex in初始化为0,a初始化为-1
__global__ void func(int *a, int *mutex){
a[0] = atomicCAS(mutex, 0, 1); // a[0] = 1
}
如果我这样做,a[0] 等于 1。但它应该是 0,因为那是互斥量的旧值。
__global__ void func(int *a, int *mutex){
a[0] = mutex[0]; // a[0] = 0
}
这是完整性检查,a[0] 的值现在为 0。这意味着 mutex 被正确初始化为 0。
您可以使用mutex to protect multithreaded access to the memory region. Cuda Programming Guide has a nice example of using atomic operations to implement it (https://docs.nvidia.com/cuda/cuda-c-programming-guide/#scheduling-example)
__device__ void mutex_lock(unsigned int *mutex) {
unsigned int ns = 8;
while (atomicCAS(mutex, 0, 1) == 1) {
__nanosleep(ns);
if (ns < 256) {
ns *= 2;
}
}
}
__device__ void mutex_unlock(unsigned int *mutex) {
atomicExch(mutex, 0);
}
好的,我知道出了什么问题。基本上只有线程块中的第一个线程获得旧值 0,同时将互斥锁设置为 1,其他线程读取互斥锁 after 第一个线程将互斥锁设置为 1,然后陷入死锁.
我发现这个 solution 对我有用。
是否可以防止某个内存地址在一段时间内被其他线程访问?例如:
__global__ void func(int* a){
// other computation
__lock_address(a);
a[0] += threadIdx.x;
__unlock_address(a);
}
第一个完成 other computations
并到达 __lock_address
的线程将锁定该内存地址,直到 _unlock_address
被调用,任何其他到达 __lock_address
的线程都必须等到第一个线程解锁它。
上面的例子基本上等同于atomicAdd
,但是如果我想做更复杂的计算而不是简单的加法呢?
编辑: mutex in初始化为0,a初始化为-1
__global__ void func(int *a, int *mutex){
a[0] = atomicCAS(mutex, 0, 1); // a[0] = 1
}
如果我这样做,a[0] 等于 1。但它应该是 0,因为那是互斥量的旧值。
__global__ void func(int *a, int *mutex){
a[0] = mutex[0]; // a[0] = 0
}
这是完整性检查,a[0] 的值现在为 0。这意味着 mutex 被正确初始化为 0。
您可以使用mutex to protect multithreaded access to the memory region. Cuda Programming Guide has a nice example of using atomic operations to implement it (https://docs.nvidia.com/cuda/cuda-c-programming-guide/#scheduling-example)
__device__ void mutex_lock(unsigned int *mutex) {
unsigned int ns = 8;
while (atomicCAS(mutex, 0, 1) == 1) {
__nanosleep(ns);
if (ns < 256) {
ns *= 2;
}
}
}
__device__ void mutex_unlock(unsigned int *mutex) {
atomicExch(mutex, 0);
}
好的,我知道出了什么问题。基本上只有线程块中的第一个线程获得旧值 0,同时将互斥锁设置为 1,其他线程读取互斥锁 after 第一个线程将互斥锁设置为 1,然后陷入死锁. 我发现这个 solution 对我有用。