-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAtomicOP.cuh
42 lines (37 loc) · 1.18 KB
/
AtomicOP.cuh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef AtomicOP_cuh
#define AtomicOP_cuh
template<class T, class Operator, size_t size>
struct AtomicOP {};
template<class T, class Operator>
struct AtomicOP<T, Operator, 4> {
__device__ static T operate(T* address, T val, Operator op) {
unsigned int* address_as_uint = (unsigned int*)address;
unsigned int old = *address_as_uint, assumed;
T current;
do {
assumed = old;
current = op(val, *((T*)&assumed));
old = atomicCAS(address_as_uint, assumed, *((unsigned int*)¤t));
} while (assumed != old);
return *((T*)&old);
}
};
template<class T, class Operator>
struct AtomicOP<T, Operator, 8> {
__device__ static T operate(T* address, T val, Operator op) {
unsigned long long int* address_as_uint = (unsigned long long int*)address;
unsigned long long int old = *address_as_uint, assumed;
T current;
do {
assumed = old;
current = op(val, *((T*)&assumed));
old = atomicCAS(address_as_uint, assumed, *((unsigned long long int*)¤t));
} while (assumed != old);
return *((T*)&old);
}
};
template<class T, class Operator>
__device__ T atomicOP(T* address, T val, Operator op) {
return AtomicOP<T, Operator, sizeof(T)>::operate(address, val, op);
}
#endif