x86平台SIMD编程入门(5):提示与技巧
1、提示与技巧
访问内存的成本非常高,一次缓存未命中可能会耗费100~300个周期。L3缓存加载需要40~50个周期,L2缓存大约需要10个周期,即使L1缓存的访问速度也明显慢于寄存器。所以要尽量保持数据结构对SIMD友好,优先选择
std::vector、CAtlArray、eastl::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、参考资料
Agner Fog的网站上有很多关于C++优化的资源。
uops网站可以方便地查询SIMD指令的性能数据。
x86/x64 SIMD Instruction List可以方便地按功能和数据类型查询对应的SIMD指令。
一文读懂SIMD指令集 目前最全SSE/AVX介绍比较全面地介绍了SIMD的基础知识,本系列随笔的第一章内容主要参考了这篇博文。
SIMD for C++ Developers比较全面地介绍了各种常用的SIMD指令,而且作者也分享了很多他在SIMD编程领域的经验与技巧,本系列随笔的第二章至最后一章内容主要参考了这份资料。
x86平台SIMD编程入门(5):提示与技巧的更多相关文章
- x86平台转x64平台关于内联汇编不再支持的解决
x86平台转x64平台关于内联汇编不再支持的解决 2011/08/25 把自己碰到的问题以及解决方法给记录下来,留着备用! 工具:VS2005 编译器:cl.exe(X86 C/C+ ...
- PC游戏编程(入门篇)(前言写的很不错)
PC游戏编程(入门篇) 第一章 基石 1. 1 BOSS登场--GAF简介 第二章 2D图形程式初体验 2.l 饮水思源--第一个"游戏"程式 2.2 知其所以然一一2D图形学基础 ...
- Matlab与.NET基于类型安全的接口混合编程入门
原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...
- VS2010MFC编程入门
一.MFC编程入门教程之目录 第1部分:MFC编程入门教程之目录 1.MFC编程入门之前言 鸡啄米的C++编程入门系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的 ...
- X86平台乱序执行简要分析(翻译为主)
多处理器使用松散的内存模型可能会非常混乱,写操作可能会无序,读操作可能会返回不是我们想要的值,为了解决这些问题,我们需要使用内存栅栏(memory fences),或者说内存屏障(memory bar ...
- VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)
VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)-软件开发-鸡啄米 http://www.jizhuomi.com/software/143.html 鸡啄米在上一讲中 ...
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html 上一讲中讲了VS20 ...
- VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)
原文地址: VS2010/MFC编程入门之一(VS2010与MSDN安装过程图解)-软件开发-鸡啄米 http://www.jizhuomi.com/software/139.html 上一讲中鸡 ...
- WinPcap编程入门实践
转自:http://www.cnblogs.com/blacksword/archive/2012/03/19/2406098.html WinPcap可能对大多数人都很陌生,我在这里就先简单介绍一下 ...
- 【浅墨著作】《OpenCV3编程入门》内容简单介绍&勘误&配套源码下载
经过近一年的沉淀和总结,<OpenCV3编程入门>一书最终和大家见面了. 近期有为数不少的小伙伴们发邮件给浅墨建议最好在博客里面贴出这本书的文件夹,方便大家更好的了解这本书的内容.事实上近 ...
随机推荐
- mybatis相关-转义字符串报错-Cause: org.xml.sax.SAXParseException
mybatis相关-转义字符串报错-Cause: org.xml.sax.SAXParseException 部分报错信息 Caused by: org.springframework.beans.f ...
- 国密SSL证书,为政务数据安全保驾护航
随着数字化转型的加速,政务信息化建设已成为提升政府服务效率和质量的关键.近期,国家相关部门发布了<互联网政务应用安全管理规定>,为政务应用的安全管理提供了明确的规范和要求.该规定自2024 ...
- 女友用python写的充值卡冲话费的代码
女友最近在学习python ,于是我拿当初我们学习C语言的课程设计 手机号充话费功能让她尝试着做一下,在分析完思路和帮助改错的情况下代码如下: python2.7.17 环境 #/usr/bin/py ...
- 什么是静态方法?@staticmethod装饰器怎么用?
填坑(@staticmethod装饰器----静态方法声明) > 在学习的时候看到很多人都在用@Staticmethod这个装饰器来修饰类方法,这就让我好奇了这个独特的装饰器到底是个啥?咋就受到 ...
- 基本数据结构-双端队列(Deque)
6.基本数据结构-双端队列(Deque) 一.双端队列(Deque) - 概念:deque(也称为双端队列)是与队列类似的项的有序集合.它有两个端部,首部和尾部,并且项在集合中保持不变. - 特性:d ...
- SQL 语法解释器jsqlparser
是用java 开发的解析器, 可以生成java类层次结构. 主页地址: http://jsqlparser.sourceforge.net 可以完美解析 表的 增删查改等操作. 展开它的源码你会发现. ...
- pve 下的群晖虚拟机硬盘空间扩容的记录
pve下,105号群晖虚拟机,btrfs系统,sata硬盘. 虚拟机容量硬盘130G,扩展至140G,还需要命令行和网页存储管理器界面操作,以实现扩容的目的. df -h Filesystem Siz ...
- 第十四届蓝桥杯省赛C++B组--接龙序列
接龙序列 我们称序列中\(a_i\)的首位数字恰好是\(a_{i-1}\)的末尾数字,这样的序列叫做接龙序列,比如12 23 35 57,所有长度为1的整数序列都是接龙序列,现在给定一个长度为\(n\ ...
- 编译器-FIRST集合
语法分析器的两个重要函数 FIRST和FOLLOW FIRST的定义 FIRST(α),可从α推导得到的串的首符号的集合 1.如果X是一个终结符,那么FIRST(X) = X 2.如果X是一个非终 ...
- Java 设计模式——从冰雪经济看设计模式的综合运用(工厂、单例、策略、观察者)
当冬季的寒风拂过大地,冰雪经济如同一颗璀璨的明珠,在寒冷中散发着炽热的魅力.滑雪场.冰雕展.冰雪主题酒店等各类冰雪产业蓬勃发展,其背后的运营逻辑和策略,与 Java 设计模式有着奇妙的相似之处,为我们 ...