我经常在张量流代码中看到转置实现。我想知道为什么要将NHWC张量转换为NCHW。请给我一个很好的例子和背后的原因。
答案 0 :(得分:2)
而不是引用文档。您应该了解CUDA的工作原理并思考如何实施大多数操作。
NCHW通常比NHWC更快的原因是CUDA内核的编写方式。在CUDA中,您需要指定每个线程正在执行的操作
-config:yourconfiguationfile.xml
这里有3个指数const int threads = 32;
dim3 block(threads, threads);
dim3 grid(up2(W / 2, threads), up2(H, threads), B);
kernel<Dtype> <<< grid, block>>> (args ...)
。这些线程以warp(硬件设计)组织。
并且您希望拥有合并内存事务,这意味着线程以这样的方式排序,以便GPU可以快速地运行。
总结一下: 你想让“threadId.x”成为最内循环,你应该组织数据布局,使它以合并的方式读取它们。
可以访问理想的数据结构threadId.z, threadId.y, threadId.x
其中低位字母表示索引,大写字母表示形状(例如,0 <= w 在卷积运算(最常用层的一部分)中,您实际上正在做的是在每个通道中裁剪一个区域,计算另一个通道中的区域(来自另一个张量)的点生成。所以需要快速运行的索引是height-idx和width-idx。最后,您将沿通道轴添加(如卷积公式建议)。这也解释了为什么考虑NWHC,NCWH没有区别。 这会对您订购数据的方式产生影响。这就是你想要我上面描述的内存布局的原因。 最糟糕的布局是: 最佳布局是: 同样(大多数情况下)对于GEMM也是如此(这里一个矩阵应该是转置的)。没有可用的CuDNN来源。但您可能有兴趣研究cutlass。b * C * H * W + c * H * W + h * W + w
H, C, B, in threadId.z, threadId.y, threadId.x
答案 1 :(得分:1)
来自Tensorflow的performance guide:
NHWC是TensorFlow的默认值,NCHW是最佳使用格式 使用cuDNN在NVIDIA GPU上进行培训时。 [...]这两种格式的简要历史是TensorFlow使用NHWC开始,因为它在CPU上的速度要快一些。从长远来看,我们正在研究自动重写图形的工具,以便在格式之间进行透明切换,并利用微优化,其中使用NHWC的GPU Op可能比通常最有效的NCHW更快。
基本上,cuDNN针对NCHW进行了优化,而仅限CPU的张量流针对NHWC进行了优化。从一个切换到另一个只是性能最大化和/或特定数据格式中某些操作不可用的问题。