CUDA Memory Fence A technical blog post explains that CUDA provides three memory fence functions — `__threadfence_block`, `__threadfence`, and `__threadfence_system` — to enforce sequentially-consistent ordering on memory accesses that compilers may otherwise reorder for performance. The post illustrates the problem with a two-thread example in which a compiler could reorder a flag assignment ahead of a data write, causing a reader to print `x = 0` instead of `x = 42`, and notes the three functions differ in scope: thread block, device, and system-wide visibility including host threads and peer devices. CUDA Memory Fence Because the compiler can do lots of optimizations for performance, the order of memory accesses in the machine code might not be the same as the order of memory accesses implemented in the source code. If the memory is only accessed by a single thread in the program, the memory access order changed by the compiler usually does not matter. Otherwise it is a compiler bug. However, if the memory is accessed by multiple threads or even multiple processes, the memory access order has to be carefully managed. In many cases, we don’t want the compiler to optimize the memory access order for those which are critical for the desired program behavior. This is a common problem in parallel programming not only for multi-threaded CPU programming but also for CUDA programming on GPU. In CUDA programming, we can use CUDA memory fence functions to enforce a sequentially-consistent ordering on memory accesses. In this blog post, I would like to discuss the memory fence functions and their motivations in CUDA programming. In computing, a memory fence or memory barrier, is a type of fence instruction that causes a processor or compiler to enforce an ordering constraint on memory operations issued before and after the fence instruction. This typically means that operations issued prior to the fence are guaranteed to be performed before operations issued after the fence. The following example shows why memory fence is necessary in parallel programming. Suppose we have two threads, one thread is modifying a variable x , and the other thread is printing the modified x . | 1234567891011121314151617 | include