1、提示与技巧

  • 访问内存的成本非常高,一次缓存未命中可能会耗费100~300个周期。L3缓存加载需要40~50个周期,L2缓存大约需要10个周期,即使L1缓存的访问速度也明显慢于寄存器。所以要尽量保持数据结构对SIMD友好,优先选择std::vectorCAtlArrayeastl::vector等容器,按照顺序读取数据以提高缓存命中率。如果数据比较稀疏,可以将其组织为小型密集块的稀疏集合,其中每个块的大小至少为1个SIMD寄存器的大小。如果需要遍历链表或图,同时对每个节点进行计算,可以使用_mm_prefetch函数来将数据预先加载到缓存中。

  • 为了获取最佳性能,内存访问需要内存对齐。更具体地说,内存访问不应该超出缓存行(cache line)的边界。缓存行的大小为64字节,且按64字节地址对齐。当SIMD向量正确对齐(SSE向量16字节对齐、AVX向量32字节对齐)时,内存访问将保证只触及一个缓存行。

  • 在处理成对的32位浮点数(如2D平面中的FP32向量)时,可以用一条FP64数的指令加载或存储两个标量,我们只需要对指针进行类型转换,并对向量使用_mm_castps_pd/_mm_castpd_ps函数即可。同样,我们也可以随意使用FP64洗牌/广播函数来移动这些向量中的FP32值对。

  • C++有很多优秀的矢量化库,例如Eigen、DirectXMath等,它们已经实现了相当复杂的功能,有时候直接使用它们就好了,没必要再重复造轮子。

  • 不要在函数或方法中写入类似static const __m128 x = something();这样的语句,因为在现代C++中,这种结构保证了线程安全,而为了支持语言标准,编译器必须输出一些模板代码,这些代码可能会有锁和分支。我们可以将该值放在全局变量中,这样它们就能在main()开始运行前被初始化,或者在DLL的LoadLibrary返回前被初始化。或者,也可以将该值放在一个本地非静态常量中。

  • 如果使用VC++,请在频繁调用的循环体中对性能敏感的SIMD函数使用__forceinline修饰符。指令经常会包含幻数(magic number),或是不随循环而改变的常量。与标量代码不同的是,SIMD常量通常来自内存而不是指令流,当编译器被告知__forceinline时,它可以加载这些SIMD常量一次,并在循环过程中将它们保存在向量寄存器中(除非寄存器短缺导致它们被放到内存)。如果没有内联,代码将在执行函数时重新加载这些常量。VC++的内联功能对于标量代码是适用的,但对SIMD代码却基本不起作用,所以需要使用__forceinline来强制内联。GCC和Clang的内联功能会更好,但强制内联有时候仍有帮助,可以将__forceinline定义为宏:

    #define __forceinline inline __attribute__((always_inline))
  • 如果要根据硬件支持的指令集来动态选择函数的实现版本,请在调用函数指针或虚类方法时使用__vectorcall调用约定,这样函数会尽量在向量寄存器中传递参数与返回值。

2、参考资料

x86平台SIMD编程入门(5):提示与技巧的更多相关文章

  1. x86平台转x64平台关于内联汇编不再支持的解决

    x86平台转x64平台关于内联汇编不再支持的解决     2011/08/25   把自己碰到的问题以及解决方法给记录下来,留着备用!   工具:VS2005  编译器:cl.exe(X86 C/C+ ...

  2. PC游戏编程(入门篇)(前言写的很不错)

    PC游戏编程(入门篇) 第一章 基石 1. 1 BOSS登场--GAF简介 第二章 2D图形程式初体验 2.l 饮水思源--第一个"游戏"程式 2.2 知其所以然一一2D图形学基础 ...

  3. Matlab与.NET基于类型安全的接口混合编程入门

    原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...

  4. VS2010MFC编程入门

    一.MFC编程入门教程之目录 第1部分:MFC编程入门教程之目录 1.MFC编程入门之前言  鸡啄米的C++编程入门系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的 ...

  5. X86平台乱序执行简要分析(翻译为主)

    多处理器使用松散的内存模型可能会非常混乱,写操作可能会无序,读操作可能会返回不是我们想要的值,为了解决这些问题,我们需要使用内存栅栏(memory fences),或者说内存屏障(memory bar ...

  6. VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)

    VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html   鸡啄米在上一讲中 ...

  7. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  8. VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)

    原文地址: VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)-软件开发-鸡啄米 http://www.jizhuomi.com/software/139.html   上一讲中鸡 ...

  9. WinPcap编程入门实践

    转自:http://www.cnblogs.com/blacksword/archive/2012/03/19/2406098.html WinPcap可能对大多数人都很陌生,我在这里就先简单介绍一下 ...

  10. 【浅墨著作】《OpenCV3编程入门》内容简单介绍&勘误&配套源码下载

    经过近一年的沉淀和总结,<OpenCV3编程入门>一书最终和大家见面了. 近期有为数不少的小伙伴们发邮件给浅墨建议最好在博客里面贴出这本书的文件夹,方便大家更好的了解这本书的内容.事实上近 ...

随机推荐

  1. Nuxt.js 应用中的 components:extend 事件钩子详解

    title: Nuxt.js 应用中的 components:extend 事件钩子详解 date: 2024/11/1 updated: 2024/11/1 author: cmdragon exc ...

  2. 2个月搞定计算机二级C语言——真题(7)解析

    1. 前言 本篇我们讲解2个月搞定计算机二级C语言--真题7 2. 程序填空题 2.1 题目要求 2.2 提供的代码 #include <stdio.h> int fun(char* s, ...

  3. CF980-Div2-D

    CF980-Div2-D 题意 从 \(1\) 开始决策,若选当前数,则累计贡献 \(a[i]\) 并跳到 \(j\) 位置,\(j\) 是 \(\lt i\) 且没有决策过(包括选了和没选)的最大位 ...

  4. docker bulid tag push到自己的docker hub 仓库

    -t(或 --tag)参数:用于给构建的镜像指定标签(tag).标签的格式通常是 [仓库名/][用户名/]镜像名:版本号 -f(或 --file)参数: 指定构建镜像所使用的 Dockerfile 的 ...

  5. UML 基础:类图

    这是关于统一建模语言.即UML 里采用的基本图的一系列文章的一部分.在我 先前关于序列图的文章 里,我把重点从 UML 1.4 版,转移到 OMG的采用UML 2.0版草案规范(又称为UML 2).在 ...

  6. Java多线程设计模式之线程池模式

    前序: Thread-Per-Message Pattern,是一种对于每个命令或请求,都分配一个线程,由这个线程执行工作.它将"委托消息的一端"和"执行消息的一端&qu ...

  7. YOLOv8-PyQT5可视化界面

    使用PyQT5实现YOLOv8图形化界面 准备工作: 1.首先在YOLOv8环境中安装pyqt5 pip install pyqt5 pip install pyqt5-tools 然后再你的anac ...

  8. 简单理解Linux File的操作

    类Unix系统是支持多个进程打开同一个文件,进行读写. 得益于类Unix系统对于文件操作的特殊设计. 分为三个数据结构 进程表项:其中包含进程中打开的文件和设备的文件描述符.还包含该文件描述符对应的文 ...

  9. JDBC基础知识

    常见连接数据库工具: 图形化工具:点击.拖拽就可以操作数据库,对用户友好,简单对数据操作,复杂数据库操作爱莫能助 JDBC(驱动程序):调用jar包接口 窗口(命令行):输入完整SQL语句对复杂数据库 ...

  10. vue 存储cookie 与使用

    安装cookie依赖包 npm i @vueuse/integrations 安装cookie npm i universal-cookie 使用cookie import {useCookies} ...