0

0

c++如何用SIMD intrinsics加速计算 c++ AVX2指令实践【性能】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-03 12:17:09

|

193人浏览过

|

来源于php中文网

原创

AVX2向量化加速需32字节对齐内存、避免标量混用、改写热点循环;用aligned_alloc或_mm256_malloc分配,结构体字段加alignas(32),优先用_mm256_load_ps而非_loadu_ps。

c++如何用simd intrinsics加速计算 c++ avx2指令实践【性能】

用 SIMD intrinsics 加速 C++ 计算,核心是让单条指令并行处理多个数据(比如一次算 8 个 float),AVX2 是目前主流 CPU 上最实用的起点。关键不在于写满所有 intrinsic 函数,而在于对齐数据、避免混用标量逻辑、把热点循环向量化。

数据对齐与内存布局决定能否用 AVX2

AVX2 的 __m256 要求 32 字节对齐,否则运行时可能崩溃或降级为慢速路径。

  • aligned_alloc(32, size)_mm256_malloc(size) 分配内存,别用普通 newmalloc
  • 结构体字段若含 __m256,需加 alignas(32);数组声明写成 alignas(32) float data[1024];
  • 读取未对齐地址?可用 _mm256_loadu_ps(ptr),但比 _mm256_load_ps 慢 1–2 周期,尽量避免在主循环里用

典型计算模式:把标量循环改写成向量化循环

例如对两个 float 数组做加法:

// 标量版本(慢)
for (int i = 0; i < n; ++i) {
    c[i] = a[i] + b[i];
}

改成 AVX2 向量化(注意处理余数):

Motiff
Motiff

Motiff是由猿辅导旗下的一款界面设计工具,定位为“AI时代设计工具”

下载

立即学习C++免费学习笔记(深入)”;

const int simd_width = 8; // float: 256/32 = 8
int i = 0;
// 主循环:8 个一组,要求 a,b,c 地址都对齐
for (; i < n - simd_width + 1; i += simd_width) {
    __m256 va = _mm256_load_ps(&a[i]);
    __m256 vb = _mm256_load_ps(&b[i]);
    __m256 vc = _mm256_add_ps(va, vb);
    _mm256_store_ps(&c[i], vc);
}
// 尾部剩余元素(0–7 个),用标量补全
for (; i < n; ++i) {
    c[i] = a[i] + b[i];
}

常见陷阱与优化技巧

写对了 intrinsic 不代表快,这些细节常拖累性能:

  • 避免频繁的 load/store 与标量混合:比如在循环内用 _mm256_store_ss 存单个 float,会破坏流水线;尽量保持整组运算
  • 减少跨寄存器 shuffle:如 _mm256_shuffle_ps 开销大,能用广播(_mm256_broadcast_ss)或直接重排数据就别 shuffle
  • -mavx2 -O2 编译,禁用 -ffast-math 外的激进优化:GCC/Clang 需显式开 AVX2,且 -O2 才会做基本的向量化识别;但编译器自动向量化(如 #pragma omp simd)有时不如手写稳定
  • 查 CPU 支持再运行:用 __builtin_cpu_supports("avx2")(GCC/Clang)或 cpuid 检测,避免在老 CPU 上非法指令崩溃

验证是否真加速:别只看理论吞吐

实际提速受内存带宽、缓存命中率、指令依赖链影响。推荐做法:

  • std::chrono::high_resolution_clock 测端到端耗时,重复多次取中位数
  • 对比同一机器上标量 vs AVX2 版本,输入规模 ≥ L2 缓存(如 256KB 以上),排除 cache warmup 干扰
  • 用 perf(Linux)或 VTune(Intel)看 uops_retired.allmem_inst_retired.all_stores,确认没卡在内存或分支预测上

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

554

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

95

2025.10.23

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

186

2025.07.04

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1345

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

700

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

294

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

773

2023.07.05

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

177

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.5万人学习

Git 教程
Git 教程

共21课时 | 2.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号