x86平台SIMD编程入门(5):提示与技巧

这篇具有很好参考价值的文章主要介绍了x86平台SIMD编程入门(5):提示与技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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、参考资料

  • Agner Fog的网站上有很多关于C++优化的资源。

  • uops网站可以方便地查询SIMD指令的性能数据。

  • x86/x64 SIMD Instruction List可以方便地按功能和数据类型查询对应的SIMD指令。

  • 一文读懂SIMD指令集 目前最全SSE/AVX介绍比较全面地介绍了SIMD的基础知识,本系列随笔的第一章内容主要参考了这篇博文。

  • SIMD for C++ Developers比较全面地介绍了各种常用的SIMD指令,而且作者也分享了很多他在SIMD编程领域的经验与技巧,本系列随笔的第二章至最后一章内容主要参考了这份资料。文章来源地址https://www.toymoban.com/news/detail-741781.html

到了这里,关于x86平台SIMD编程入门(5):提示与技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • x86 平台运行 arm 的方法

    参考: https://github.com/multiarch/qemu-user-static 核心是使用 binfmt_misc 设定运行 arm 的默认程序为 qemu-aarch64-static 1.先下载 arm64 即 aarch64 的运行文件 2.设置默认打开方式, 即设置 binfmt_misc 以支持 arm64 程序的运行 # --reset 会删除同名条目后重新设置 3.测试 4.不用映射qemu-*-static也可以使用

    2024年02月12日
    浏览(209)
  • docker在x86平台下载arm的镜像

    6、进入该arm版本的详细页面,在该页面的上方有本版本镜像的sha校验值。 7、复制该值,使用如下命令在x86平台上进行下载即可。 docker pull nginx:latest@sha256:687e0e4a235ee770533f6c25fb5791b14d7b6aa603ba4ed724abbd2ed51ee11a 8、完成下载,如图:

    2024年02月12日
    浏览(57)
  • Mac x86 Ollama使用入门

    Mac上可以本地运行大模型,作为Mac x86硬件,比较好的选择是Ollama,但有一些准备工作,需要明确一下,否则坑也会比较多。 1、下载地址: 官网 2、也可以通过安装Docker Desktop(下载: x86 Docker Desktop),再下载Docker官方的Ollama。 3、安装Ollama并运行命令:ollama run gemma 4、安装

    2024年04月26日
    浏览(29)
  • x86 平台利用 qemu-user-static 实现 arm64 平台 docker 镜像的运行和构建

    因为国产化的普及,尤其一些证券和银行行业,已经开始走信创的路线,后期也许会接触到国产 CPU ( arm 平台,比如华为的鲲鹏处理器) 自己买 arm 平台的 CPU ,这个成本着实吃不消,于是尝试 x86 平台运行 arm 平台的容器来降本增效 docker 运行其他平台容器,需要使用 --pla

    2024年02月02日
    浏览(33)
  • 2023年的深度学习入门指南(9) - SIMD和通用GPU编程

    深度学习从一开始就跟GPU有不解之缘,因为算力是深度学习不可或缺的一部分。 时至今日,虽然多任务编程早已经深入人心,但是很多同学还没有接触过CPU上的SIMD指令,更不用说GPGPU的编程。这一篇我们先给SIMD和GPU编程扫个盲,让大家以后用到的时候有个感性认识。 从多线

    2024年02月02日
    浏览(34)
  • Linux操作系统下Docker和Docker Compose的安装教程(包含x86和arm64平台离线一键安装资源包)

    本文章将详细介绍Linux下Docker和Docker Compose的安装教程。 目录3为x86和arm64平台Docker离线安装资源包,包含Docker Compose、一键安装脚本使用教程。 相关文章参考: Docker常用基础命令 Docker批量清理删除镜像和容器常用命令 版本如下 名称 版本 CentOS 7.6+ openEuler等其他操作系统可以使

    2024年02月06日
    浏览(32)
  • ARM和X86、X86和X64、Intel和AMD、CPU和GPU介绍

    X86 和 ARM 都是CPU设计的一个架构。X86 用的是复杂指令集。ARM用的是精简指令集。 指令集其实就是机器码,机器码上是汇编,汇编之上是程序语言例如java、c、c#。 复杂指令集是在硬件层面上设计了很多指令,所以编程会简单些。 精简指令集是在硬件层面上设计的指令比较少

    2024年02月04日
    浏览(30)
  • 安装Android x86

    一台电脑(需要预装Windows) 一块U盘 Phoenix OS 或 Bliss OS 有关的文件,取决于你想安装谁 UltraISO【可选】 提到安卓系统,大家首先想到的应该是手机吧。市面上卖的手机,除了苹果系统就是安卓系统(虽然也会有很少很少一部分手机安装的是Linux或Windows)。但如果我希望在电

    2024年02月08日
    浏览(33)
  • 在windows内使用virtualbox搭建安卓x86,以及所遇到的问题解决--2.virtualbox上安卓x86的配置

    目录: 简要说明: 1.配置vesa驱动: 2.启用网络连接并配置adb: 3.增强性能的方法: 简要说明: 先进行说明一点个人直接通过vbox VMware这些软件,并不能超越专业的安卓模拟器,大部分模拟器实际也是基于vbox(腾讯傲引擎和网易星云比较特殊,使用了aow),但是仍然存在不同。

    2023年04月16日
    浏览(38)
  • X86和arm的区别

    硬件上的区别 x86 系统中的硬件组件(如声卡、显卡、内存、存储器和 CPU)都是相互独立的。大多数组件都有单独的芯片,称为控制器。我们可以对这些组件进行更改或扩展,而不会影响连接性或整个硬件平台。 ARM 处理器没有单独的 CPU。相反,处理单元与其他硬件控制器位

    2024年02月03日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包