求助解析_mm512_mask_loadunpacklo_epi32指令含义(AVX-512入门)
理解AVX-512的
_mm512_mask_loadunpacklo_epi32内在函数 先搞懂doubleword stream(双字流)
这就是个简单概念:x86体系里的doubleword指32位(4字节)数据,所以双字流就是内存中连续的32位整数序列,比如你代码里addrF指向的连续int32_t数组,就是典型的双字流。
拆解_mm512_mask_loadunpacklo_epi32的核心逻辑
这个函数是AVX-512里带掩码的加载+重组函数,参数为v1_old(初始向量)、vecMask(16位写掩码,对应__m512i里的16个int32_t元素)、mt(内存起始地址),具体做这几件事:
- 定位内存:找到
mt之后第一个64字节对齐的地址(AVX-512向量刚好是64字节,对应16个int32_t) - 读取数据:从这个对齐地址开始,读取连续的双字,读取数量等于
vecMask中置位(为1)的位数 - 写入向量:把读取到的双字,按
vecMask的置位位置写入结果向量——掩码置位的位置用新读取的值,未置位的位置保留v1_old的原值 - 注意
lo的含义:只处理mt之后第一个64字节对齐地址及之后的双字,对应的_mm512_loadunpackhi_epi32负责处理mt之前的64字节对齐地址部分
分析你的代码示例
你的代码里addrF是用_mm_malloc分配的64字节对齐内存,所以addrF本身就是64字节对齐地址:
- 第一行:
vecData1 = _mm512_mask_loadunpacklo_epi32(vecZero, vecMask, addrF);- 初始向量
vecZero是全0,vecMask里哪几位是1,就从addrF起始位置读取对应数量的int32_t,写入vecData1的对应位置;掩码未置位的位置保持0。
- 初始向量
- 第二行:
vecData1 = _mm512_mask_loadunpacklo_epi32(vecData1, vecMask, addrF+16);addrF+16是跳过16个int32_t(刚好64字节),也就是下一个64字节对齐地址。- 这里用之前的
vecData1作为初始向量,vecMask置位的位置会被addrF+16起始的新int32_t覆盖,未置位的位置保留原来vecData1的值。
补充:非对齐向量加载的用法
如果mt不是64字节对齐的(比如只满足元素对齐,不满足向量对齐),单独用对齐加载函数会报错,这时候可以配合两个函数实现非对齐加载:
v1 = _mm512_loadunpacklo_epi32(v1, mt); v1 = _mm512_loadunpackhi_epi32(v1, mt+64);
lo版本读取mt之后第一个对齐地址的内容,hi版本读取mt之前的对齐地址的内容,两者配合就能把mt前后两个缓存行的内容组合成完整的向量。
内容的提问来源于stack exchange,提问作者AoShen
相关产品推荐
相关产品推荐

