Intrinsics函数Tips与踩坑

Intrinsics函数踩坑,感觉用Intrinsics函数,最重要的是不能想当然,只有想不到。。还是得参考官方文档

一系列乘法MUL——_mm256_mul_epi32

在这里插入图片描述
这个乘法会把32位的两个整数扩展为64位再相乘,最后结果竟然存成64位!!如果要存为32位的数,应该用下面的函数_mm256_mullo_epi32

一系列set——_mm256_set_epi32

set函数的都是这样,参数顺序是反的。而且似乎性能巨差
在这里插入图片描述
看汇编可以发现,set是调用了多轮insertf指令,一点点构建向量。

整数load——_mm512_load_epi32

第一次做把int数组加载到zmm寄存器中的时候,想当然的用了_mm512_load_epi32这个函数,结果编译的时候报错,找不到对应的函数,才发现load一个int类型的数组要用这个函数_mm512_loadu_si512
在这里插入图片描述
一看到这个函数,我就发现自己格局小了,,反正是load连续512位的内存,何必区分位数呢。
进一步想,为什么浮点数类型就要区分精度了呢?推测是__mm512i和__mm512两个结构的区别。

loadu和load

区别很明显,load要求内存对齐,而loadu不要求,似乎是在汇编层面上做了什么操作?
内存地址对齐的方法:
1.利用struct,挺多博客讲的,不过似乎不同编译器对齐原则稍有差别(需要考证),附一篇写的很好的博客
2.#pragma pack预编译指令
3._mm_free与_mm_malloc
4.手动对齐,下面的代码通过先开辟空间再手动对齐的方式,完成了对pvbQueryProf、pvsQueryProf、pvH1、pvH2、pvE空间的分配

pSwData->pData = (unsigned char *) calloc (nCount, sizeof (__m256i));
    if (!pSwData->pData) {
        fprintf (stderr, "Unable to allocate memory for SW data buffers\n");
        exit (-1);
    }

    /* since we might port this to another platform, lets align the data */
    /* to 16 byte boundries ourselves */
    aligned = ((size_t) pSwData->pData + 15) & ~(0x0f);//对齐

    pSwData->pvbQueryProf = (__m256i *) aligned;
    pSwData->pvsQueryProf = pSwData->pvbQueryProf + lenQryByte * ALPHA_SIZE;

    pSwData->pvH1 = pSwData->pvsQueryProf + lenQryShort * ALPHA_SIZE;
    pSwData->pvH2 = pSwData->pvH1 + lenQryShort;
    pSwData->pvE  = pSwData->pvH2 + lenQryShort;

shift

_mm128_slli_si128函数是将128位的xmm寄存器整体左移n个byte,而_mm256_slli_si256是将两个256位的ymm寄存器按128位为一个整体左移。
在这里插入图片描述
可以通过如下的形式实现了256位寄存器的整体左移与右移操作,其中A为源寄存器,N为移动的字节数:
左移:
_mm256_alignr_epi8(A, _mm256_permute2x128_si256(A, A, _MM_SHUFFLE(0, 0, 2, 0)), 16 - N)
右移:
_mm256_alignr_epi8(_mm256_permute2x128_si256(A, A, _MM_SHUFFLE(2, 0, 0, 1)), A, N)

不规则内存读写——gather和scatter

非常牛的两种CPU特性,gather和scatter,一个读一个写,具体看图
在这里插入图片描述
在这里插入图片描述

类型转换

最有用的是cvt系列的指令,比如_mm256_cvtepi16_epi32
在这里插入图片描述
还有extractf,可以用来提取向量中的一部分

一个了解向量化指令的方法

从一位学长那学来的,可以写一个方便自动向量化的简单循环,看一下这个循环的汇编即可

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值