资源:https://download.csdn.net/download/Rong_Toa/18745608

《Benefits of SIMD Programming | SIMD的优势》

目录

SIMD指令编程demo

正常代码

一次循环计算4次

使用SSE指令

使用AVX指令

性能对比

更多参考


SIMD指令编程demo


本文更新于 2018.10.24

本demo主要使用矩阵相乘, 演示了Intel SSE和AVX内部指令(intrinsics)的显式使用, 并对比了使用gcc和icc(Intel C/C++编译器)使用不同编译选项编译后的代码性能.

完整源码见: https://raw.githubusercontent.com/zzqcn/storage/master/code/c/simd_multiply.c

参考: https://software.intel.com/zh-cn/articles/ticker-tape-part-2

本文的软硬件环境如下:

  • CPU: Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz
  • 操作系统: CentOS Linux release 7.0.1406
  • 内核: 3.10.0-123.el7.x86_64
  • gcc: 4.8.5 20150623
  • icc: 19.0.0.120 20180804

正常代码


正常代码如下, 直接使用基本算法计算2个矩阵a和b, 结果放在c中:

void multiply(void) {unsigned i;for(i=0; i<N; i++) {c[i] = a[i] * b[i];}
}

一次循环计算4次


可以将正常代码改为一次循环内计算4次乘法, 某种情况下可以提升性能:

void multiply(void) {unsigned i;for(i=0; i<(N & ((~(unsigned)0x3))); i+=4) {c[i]   = a[i]   * b[i];c[i+1] = a[i+1] * b[i+1];c[i+2] = a[i+2] * b[i+2];c[i+3] = a[i+3] * b[i+3];}for(; i<N; i++) {c[i] = a[i] * b[i];}
}

使用SSE指令


Intel SSE指令通过128bit位宽的专用寄存器, 支持一次操作128bit数据. float是单精度浮点数, 占32bit, 那么可以使用一条SSE指令一次计算4个float数:

void multiply(void) {unsigned i;__m128 A, B, C;for(i=0; i<(N & ((~(unsigned)0x3))); i+=4) {A = _mm_load_ps(&a[i]);B = _mm_load_ps(&b[i]);C = _mm_mul_ps(A, B);_mm_store_ps(&c[i], C);}for(; i<N; i++) {c[i] = a[i] * b[i];}
}

注意这些SSE指令要求参数中的内存地址必须对齐于16字节边界, 所以可以用以下函数分配内存:

a = (float*) _mm_malloc(N*sizeof(float), 16);
b = (float*) _mm_malloc(N*sizeof(float), 16);
c = (float*) _mm_malloc(N*sizeof(float), 16);

要使用这些intrinsics, 需要包含x86intrin.h头文件.

使用AVX指令


较新的Intel CPU都支持AVX指令集, 它可以一次操作256bit数据, 是SSE的2倍. 使用AVX的代码如下:

void multiply(void) {unsigned i;__m256 A, B, C;for(i=0; i<(N & ((~(unsigned)0x7))); i+=8) {A = _mm256_load_ps(&a[i]);B = _mm256_load_ps(&b[i]);C = _mm256_mul_ps(A, B);_mm256_store_ps(&c[i], C);}for(; i<N; i++) {c[i] = a[i] * b[i];}
}

AVX指令要求内存地址对齐于32字节边界, 所以内存分配代码改为:

a = (float*) _mm_malloc(N*sizeof(float), 32);
b = (float*) _mm_malloc(N*sizeof(float), 32);
c = (float*) _mm_malloc(N*sizeof(float), 32);

性能对比


我分别使用gcc和icc以默认选项和-O3选项编译了以上3种版本的代码, 其中用gcc编译AVX版代码时需要加-mavx选项.

代码执行时间如下(单位毫秒):

代码版本 gcc gcc -O3 icc icc -O3
原始 946 438 405 404
每次计算4项 780 438 439 442
SSE 680 439 405 406
AVX 545 447 407 406

代码执行时间是连续运行10次取的平均值. 某些时候执行时间起伏时间较大. 下图是根据上表生成的对比图:

由上图可知:

  • 现代编译器在-O3编译时会对代码进行充分优化, 使得本文中的代码无论使不使用SIMD指令性能差距不大
  • gcc编译器默认编译时未对代码进行充分优化, 使得不同算法的代码性能差距较大
  • intel编译器对-O3编译选项不敏感, 总是会自动优化代码

更多参考

  • Intel 64 and IA-32 Architectures Software Developer’s Manual
  • Intel Intrinsics Guide

SIMD 编程的优势与SIMD指令:SSE/AVX 与编程demo相关推荐

  1. 单指令多数据SIMD的SSE/AVX指令集和API

    https://software.intel.com/sites/landingpage/IntrinsicsGuide/# Technologies MMX SSE SSE2 SSE3 SSSE3 ...

  2. 一文读懂SIMD指令集 目前最全SSE/AVX介绍

    SIMD指令集 SSE/AVX 概述 参考手册 Intel® Intrinsics Guide Tommesani.com Docs Intel® 64 and IA-32 Architectures ...

  3. SIMD(MMX/SSE/AVX)变量命名规范心得

    [转载]:SIMD(MMX/SSE/AVX)变量命名规范心得 当使用Intrinsics函数来操作SIMD指令集(MMX/SSE/AVX等)时,会面对不同长度的SIMD数据类型,其中又分为多种紧缩格式 ...

  4. cmd指令大全指令_数控加工中心编程技巧及指令大全,请转给需要的数控人!

    大家好,人生最可贵的两个词,一个叫认真,一个叫坚持,认真的人改变了自己,坚持的人改变了命运.有些事情,不是看到了希望才去坚持,而是坚持了才有希望.如果你相信我,我有能力,有实力把你教会.只要你想学习, ...

  5. 学习C++编程的优势有哪些?

    目前很多人都想要转行成为C++开发工程师,这不仅是因为C++开发工程师的待遇,同时也是因为学习C++编程的优势.那么学习C++编程的优势有哪些? 学习C++编程的优势有哪些? 语言稳定.永不过时,C+ ...

  6. c语言延空指令,单片机C语言编程空指令产生短延时怎么办.doc

    单片机C语言编程空指令产生短延时怎么办.doc (6页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 7.9 积分 个人收集整理-仅供参考单片机语言编程空 ...

  7. 举出其他监督学习,无监督学习,强化学习的例子?说一下非显著式编程的优势?AlphaGo的胜利,带给我们什么样的人生启示?当代大学生如何在人工智能时代增加自己的核心竞争力?

    (1)举出其他监督学习,无监督学习,强化学习的例子 监督学习:比如手写体识别,我们将许多汉字的手写数字图像数据作为训练数据.汉字的数据的分类目标被称作标签和类.训练数据有一个标签(某一个汉字),根据标 ...

  8. python编程优势_Python编程的优势是什么

    Python编程的优势是什么 发布时间:2020-06-26 13:54:14 来源:亿速云 阅读:110 作者:Leah Python编程的优势是什么?针对这个问题,这篇文章详细介绍了相对应的分析和 ...

  9. CUDA编程(一):GPU计算与CUDA编程简介

    CUDA编程(一):GPU计算与CUDA编程简介 GPU计算 GPU硬件资源 GPU软件资源 GPU存储资源 CUDA编程 GPU计算 NVIDIA公司发布的CUDA是建立在GPU上的一个通用并行计算 ...

最新文章

  1. 关于计算机中二进制原码,反码,补码的简要解释
  2. 零基础可以学好UI设计吗
  3. R语言生存分析(survival analysis)与生存资料有关的概念详解
  4. 全国知名高校网站挂马现象严重 考生面临安全风险
  5. MongoDB 入门篇
  6. MarkDown常用技巧总结
  7. 文件系统_Docker文件系统实战
  8. apm飞控制作_传统直接转矩控制
  9. webSSH如何安装?如何使用?解决Web端远程连接终端~~运维篇
  10. 视频处理中各个分辨率/数字电视系统显示格式 的介绍(QCIF,CIF,4CIF,D1,720P,1080I,1080P等)
  11. QT中的.pro文件,以及.pri .prj .prl文件说明
  12. Kafka容错性测试
  13. PyTorch学习之误差反向传播
  14. linux查看网络端口状态命令行,Linux下用netstat查看网络状态、端口状态
  15. 开源项目(VC++,MFC)
  16. 生成的分子图像是否可以识别为SMILES,然后再将识别后的SMILES转换为图像?
  17. 解决“attempted relative import with no known parent package“的错误
  18. 视频异常检测 综述(一)
  19. python search用法,Python-re中search()函数的用法详解(查找ip)
  20. 西部数据My Passport Ultra炫彩风暴引爆移动存储市场

热门文章

  1. 如何配置struts+hibernate,基本使用方法
  2. 【Mysql高级语法:视图操作】
  3. MATLAB中的eps
  4. 利用存储过程录入连续的素数序列
  5. MySQL 性能分析 之 联合索引(复合索引)实践分析
  6. 你不知道的JS之作用域和闭包(二)词法作用域
  7. Django的rom
  8. java 关于JDBC和DAO模式使用
  9. (二)原生JS实现 - 事件类方法
  10. 对DNN的一些高层架构设想