在现代GPU(比方说,Kepler)上,如果我从单个线程获得4个独立的全局内存读取(读取之间没有依赖关系),那么所有4个读取都将立即流水线化,因此我只支付延迟惩罚单个全局内存读取?共享内存怎么样?一次可以在管道中读取多少读取,这是在某处记录的吗?
答案 0 :(得分:1)
GPU线程不能以这种方式工作。从单个线程读取的多个全局内存永远不会被组合。
然而,如果它们同时启动,则可以组合来自不同线程的多个全局存储器读取,并且它们正在读取的位置在128字节内。这发生在warp(一组始终执行相同指令的线程)中。例如,如果经线中的线程0~31读取input[0~31]
类型的float
。所有这些读取将合并为一个内存事务(假设数据已正确对齐)。但是如果warp读取input[0,2,4,...,62]
中的线程0~31,则这些读取将合并为两个存储器事务,并且将读取和放弃一半数据。
对于共享内存,延迟比全局内存访问小约100倍。这里主要关注的是避免银行冲突。
您可能需要阅读以下链接以获取更多信息。
https://devblogs.nvidia.com/parallelforall/how-access-global-memory-efficiently-cuda-c-kernels/
https://devblogs.nvidia.com/parallelforall/using-shared-memory-cuda-cc/
http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#memory-hierarchy
http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#maximize-memory-throughput
http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#device-memory-spaces