利用openmp实现矩阵相乘算法加速。(矩阵自拟)_AI | 如何实现高速卷积?深度学习库使用了这些「黑魔法」...

dfd7e37f3ebf84ac4a6190c596984652.png
文章申明
文章作者:Manas Sahni
责任编辑:薰风初入弦
微信编辑:葡萄
文章转自 微信公众号 机器之心(ID:almosthuman2014),原文链接:如何实现高速卷积?深度学习库使用了这些「黑魔法」

编者按:

使用深度学习库可以大幅加速CNN模型运行,那么这些库中的哪些具体的做法实现了这种高速度和高性能呢?佐治亚理工学院计算机科学硕士研究生Manas Sahni在自己的电脑上试验了多种方法的策略,深入剖析高速卷积的实现过程。

我的笔记本电脑CPU还可以,在TensorFlow等库的加持下,这台计算机可以在 10-100 毫秒内运行大部分常见CNN模型。2019年,即使是智能手机也能在不到半秒内运行「重量级」CNN模型。而当我自己做了一个简单的卷积层实现,发现这一个层的运行时间竟然超过2秒时,我非常震惊。

大家都知道,现代深度学习库对大部分运算具备高度优化的生产级实现。但是这些库使用了哪些人类不具备的「黑魔法」呢?它们如何将性能提升100倍?当它们「优化」或加速神经网络运算时,它们在做什么?当谈及高性能/高效DNN时,我常常问(或被问及)这些问题。

本文尝试介绍在DNN库中如何实现一个卷积层。卷积不仅是很多DNN模型中最常见和最繁重的操作,它也是导致上述高性能实现的代表性trick:一点点算法智慧 + 大量调参 + 充分利用低级架构。

本文所涉及的很多内容来自这篇开创性论文《Anatomy of High-Performance Matrix Multiplication》,这篇论文形成了线性代数库(如OpenBLAS)所用算法的基础;本文还涵盖 Stefan Hadjis 博士和 Chris Rose的教程。

  • 论文地址:https://www.cs.utexas.edu/~flame/pubs/GotoTOMS_revision.pdf
  • 教程地址:https://cs.stanford.edu/people/shadjis/blas.html

朴素卷积(Naive Convolution)

不成熟的优化是万恶之源。——Donald Knuth

在探讨优化之前,我们先来了解一下基线和瓶颈。这里是一个朴素 numpy/for-loop 卷积:

'''Convolve `input` with `kernel` to generate `output`    
input.shape = [input_channels, input_height, input_width]    
kernel.shape = [num_filters, input_channels, kernel_height, kernel_width]    
output.shape = [num_filters, output_height, output_width]
'''
for filter in 0..num_filters    
    for channel in 0..input_channels        
        for out_h in 0..output_height            
            for out_w in 0..output_width                
                for k_h in 0..kernel_height    
                   for k_w in 0..kernel_width   
                    output[filter, channel, out_h, out_h] +=   
                    kernel[filter, channel, k_h, k_w] *    
                    input[channel, out_h + k_h, out_w + k_w]

这个卷积包含6个嵌套的for loop,这里不涉及步幅(stride)、扩张(dilation)等参数。假如这是MobileNet第一层的规模,我们在纯C中运行该层,花费的时间竟然高达22秒!在使用最强悍的编译器优化后(如-O3 或 -Ofast),该卷积层的运行时间降至2.2秒。但是就一个层而言,这个速度仍然太慢了。

那么如果我使用Caffe运行这个层呢?在同一台计算机上使用Caffe运行同一个层所花费的时间仅为18毫秒,实现了100倍的加速!整个网络运行时间才大约100毫秒。

那么「瓶颈」是什么?我们应该从哪儿开始优化呢?

最内的循环进行了两次浮点运算(乘和加)。对于实验所使用的卷积层规模,它执行了8516万次,即该卷积需要1.7亿次浮点运算(170MFLOPs)。我的电脑CPU的峰值性能是每秒800亿FLOPs,也就是说理论上它可以在0.002秒内完成运行。但是很明显我们做不到,同样很明显的是,电脑的原始处理能力是非常充足的。

理论峰值无法实现的原因在于,内存访问同样需要时间:无法快速获取数据则无法快速处理数据。上述高度嵌套的for-loop使得数据访问非常艰难,从而无法充分利用缓存。

贯穿本文的问题是:如

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值