AVX代码拆分加载的性能损失及多维度影响因素技术问询
我正在优化一款数值仿真引擎的性能,主要通过重构内存布局与访问模式、重写内层循环等方式,最终借助微基准测试和CPU性能计数器开展性能对比。
我注意到,当编译器利用AVX2实现内层循环向量化时,性能会有显著提升,但同时CPU性能计数器MEM_UOPS_RETIRED.SPLIT_LOADS_PS的数值极高,Intel VTune显示该项瓶颈占比为100%。
这完全符合预期——该算法会读取数组的多个重叠“窗口”,因此输入数据几乎不会与缓存行对齐(算法本身不在本次问题讨论范围内)。按向量而非单个值加载时,这个问题会明显加剧。此类未对齐加载大多是算法必需的,因此使用AVX2时出现大量拆分加载并不意外。
根据Intel官方文档:
在整个内存层次结构中,数据以缓存行粒度移动——每行64字节。尽管这远大于整数、浮点或双精度等常见数据类型,但这些类型或其他类型的未对齐值可能跨越两个缓存行。近期Intel架构通过引入拆分寄存器处理此类情况,显著提升了“拆分加载”的性能,但拆分加载仍可能引发问题,尤其是连续大量拆分加载耗尽所有可用拆分寄存器时。
我尝试查找更多相关分析,但未找到针对性内容。通过site:stackoverflow.com split load AVX和site:stackoverflow.com AVX misalign cacheline进行检索,也未发现过往有针对性的相关问题。
我需要判断,是否值得手动重写AVX内层循环或在数据结构中插入填充以减少此类未对齐加载。若开销仅为10%,则此举纯属浪费时间。
想请教以下问题:
- 在AVX代码中,拆分加载相比无拆分加载的等效代码,性能损失大概有多大?
- 该性能特性在不同Intel CPU微架构(如Sandy Bridge、Haswell、Skylake、Icelake)之间是否存在差异?
- 不同向量大小(AVX-256与AVX-512)是否会造成区别?
- 不同工作集大小(L1、L2、L3、DRAM)下的开销是否有所不同?
内容的提问来源于stack exchange,提问作者比尔盖子

