对于哪些大小是普通加载并存储到CUDA atomic中的全局内存?
在CUDA中,对全局内存的一般读取和写入是否为原子的,如果:对于哪些大小是普通加载并存储到CUDA atomic中的全局内存?,cuda,atomic,Cuda,Atomic,在CUDA中,对全局内存的一般读取和写入是否为原子的,如果: 它是一个4字节的指令?(我想是的) 它是8字节指令还是16字节指令?(我想是的) 在以下情况下,至少在开普勒和费米通用4字节读写全局内存原子级或8/16字节指令原子级/四分之一原子级: 所有扭曲线程都访问相同的32字节L2事务块?(我想是的) 扭曲线程访问不同的32字节二级事务块,但所有扭曲线程访问相同的128字节二级缓存线?(我想没有) 所有扭曲线程访问不同的二级缓存线?(我想没有) 如果这些关于warp级别原子性的假设是正
- 它是一个4字节的指令?(我想是的)
- 它是8字节指令还是16字节指令?(我想是的)
- 所有扭曲线程都访问相同的32字节L2事务块?(我想是的)
- 扭曲线程访问不同的32字节二级事务块,但所有扭曲线程访问相同的128字节二级缓存线?(我想没有)
- 所有扭曲线程访问不同的二级缓存线?(我想没有)
如果这些关于warp级别原子性的假设是正确的,那么有没有任何方法可以利用这些知识而不冒与未来计算能力兼容的风险?读写通常发生在缓存上。当事务被发送到全局内存时,CUDA编程或内存模型中的原子性无法保证,除非使用
原子指令
例如,假设threadblock中的线程更新开普勒上L2中的4字节数量。现在,在另一个warp、threadblock或内核中的另一个线程可以在缓存线被逐出到全局内存之前,只更新L2中这4个字节中的一个。当缓存线被逐出到全局内存时,它可能无法表示原始线程甚至第二个线程写入的内容(例如,如果发生第三次写入…)
请记住,L2是回写缓存,不能禁用,并且不会被全局读写绕过,除非是原子指令。原子指令不适用于简单的读写。它适用于完整的读-修改-写循环。@罗杰·达尔:写和读也可以是非原子的或原子的。想象一个四字节的读取操作,机器将其细分为四个一字节的读取,然后一个接一个地执行。因此,可以在四次读取之间修改数据。这就是为什么读取操作不是原子的。对全局内存的读取和写入事务仅以32字节的倍数发生。关于SMs和缓存之间的事务,事务也没有细分为单个字节事务。@user3134920:谢谢,我现在明白你的意思了。这个问题不是针对CUDA编程指南的,而是针对硬件的实际行为。此外,在您的简单示例中,写入仍然是原子的。当我质疑原子性时,我的意思是这样的:线程A将浮点A(0xAAAA)写入与线程B浮点B(0xBBBB)相同的地址。结果是否保证为浮点A(0xAAAA)或浮点B(0xBBBB),这将使写入原子化,或者它也可能类似于0xAABB,这将是非原子写入?对于从同一扭曲向同一位置同时写入相同大小的数据,保证该位置中只会有一次写入。没有将写入细分为字节事务。你知道,仔细想想,我认为这个答案可能没有抓住要点。从二级缓存中写回的内容可能不是线程所写的内容(例如4个字节中有3个相同,1个字节不同),这本身并不是原子性的问题。这只是内存的状态反映了序列中的一个稍后的点——在第二个线程(或第三个etc)也写入之后。我们不是说读然后写。但是,您永远无法观察执行“一半写入”的结果。