_mm256_i32gather_epi32不同步长访存吞吐量差异原因咨询
测试背景
我正在使用_mm256_i32gather_epi32 intrinsic测量内存吞吐量与运行时长,测试所用循环代码如下:
for (int i = 0; i < len; i+=8) { const __m256i* indexes_2 = reinterpret_cast<const __m256i*>(indexes_ptr + i); __m256i index_reg = _mm256_loadu_si256(indexes_2); __m256i values = _mm256_i32gather_epi32(data_ptr, index_reg, 4); sum = _mm256_add_epi32(sum, values); }
测试通过indexes_ptr指定的索引数组改变data_ptr数组的访问模式,data_ptr数组大小为256MB,确保所有访问均为缓存未命中。测试覆盖的索引访问模式包括:
- 顺序访问:索引依次为0,1,2,3...
- 步长4访问:索引依次为0,4,8,12...
- 步长16访问:索引依次为0,16,32,48...
- 步长32访问
- 步长64访问
- 步长128访问
单条_mm256_i32gather_epi32指令会加载8个32位数值,测试系统缓存行大小为64字节,经统计不同访问模式下单次gather操作触碰的缓存行数量:
- 顺序访问:1个缓存行
- 步长4访问:2个缓存行
- 步长16、步长32、步长64、步长128访问:单次gather均触碰8个缓存行
实测结果与疑问
我原本预期步长16、32、64、128场景的运行时间与内存吞吐量相近,但实测结果存在明显差异,实测数据如下:
- 顺序访问:耗时0.13s,吞吐量16828.2607 MB/s
- 步长4:耗时0.07s,吞吐量17246.1914 MB/s
- 步长16:耗时0.918406s,吞吐量5205.1085 MB/s
- 步长32:耗时1.650566s,吞吐量4756.5279 MB/s
- 步长64:耗时1.798604s,吞吐量5440.2228 MB/s
- 步长128:耗时2.186620s,吞吐量4672.1329 MB/s
核心疑问:既然步长16、32、64、128场景下单条gather指令访问的缓存行数量均为8个,为何运行时间与内存吞吐量存在明显差异?
内容的提问来源于stack exchange,提问作者Bogi
相关产品推荐
相关产品推荐

