卷积层是卷积神经网络(CNN)中计算最密集的部分。当前实现卷积层的常用方法是将图像扩展为列矩阵(im2col)并执行并执行多通道多核(MCMK)使用现有的并行通用矩阵乘法(GEMM)库进行卷积。但是,im2col操作需要加载和存储图像数据,还需要另一个内存块来保存中间数据。
如果需要优化卷积实现,则可以选择使用SIMD指令直接实现。这种方法不会产生任何内存操作开销。
非常规则的内存访问模式带来的好处超过了浪费的存储成本。
从下面的链接开始,在链接的末尾
https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/
所以我希望知道原因。浮点运算可能需要更多的指令周期吗?或输入映像不是很大,因此它可能残留在缓存中,并且内存操作不需要访问DDR并消耗更少的周期。
答案 0 :(得分:1)
可能会阻塞GEMM的缓存,因此您可以获得大部分L1缓存命中(另请参见What Every Programmer Should Know About Memory?)。
在典型的x86 CPU上安装大型共享L3缓存不足以使事情变得高效。每核二级缓存通常为256kiB,甚至比32kiB一级缓存还慢。
与CPU核心时钟相比,内存等待时间非常慢,但是如今内存/高速缓存带宽对于快速的DDR4或L3高速缓存命中来说并不可怕。 (但是就像我说的那样,对于具有良好的缓存阻止/循环平铺功能的matmul,如果仅动态转换输入矩阵的某些部分,则可以在L1d中仍很热的时候重用数据。降低内核外带宽要求对于提高效率也很重要matmul,而不仅仅是转置一个,因此其列在内存中是连续的。)
除此之外,对内存的顺序访问对于有效的SIMD(加载多个连续元素的向量,使您可以用一条CPU指令对4个或8个压缩的float
元素进行乘/加/加运算)至关重要。即使矩阵足够小以适合L1d缓存(32kiB),在行较大的矩阵中向下滚动列也会损害吞吐量。