什么是SSE2程序集等效于内在函数?

时间:2019-01-12 11:22:04

标签: assembly sse simd intrinsics sse2

我正在使用Fasm(汇编),正在寻找与这些内在指令等效的SSE2汇编指令:

_mm_set1_epi8
_mm_cmpeq_epi8
_mm_movemask_epi8

我在哪里得到它们(网站,pdf ...)?

2 个答案:

答案 0 :(得分:6)

使用Intel Intrinsics Guide,但请注意,某些内部函数不会映射到单个指令,例如_mm_set1_epi8。对于大多数内在函数,尽管描述中列出了相应的机器指令。

您还可以使用非常有用的Compiler Explorer来查看给定内在函数的生成代码,例如this example for _mm_set1_epi8

答案 1 :(得分:6)

首先要查看它们的x86 Software Developer Manual vol.2中的内容,而不是去研究内在函数文档。或者在https://www.felixcloutier.com/x86/index.html上仅提取指令条目的HTML,而没有介绍和附录。例如https://www.felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html

((Intel的asm手册条目在条目的底部列出了该指令的内在函数。由于AVX512是主PDF的一部分,所以这些列表变得一团糟,但是您仍然可以从另一个方向检查您的猜测/内存如果您已经猜到了将用于内部函数的指令并进行了查找。  或者,如果您搜索的是完整的PDF版本,则内在名称会受到打击,因为直接映射到_mm_cmpeq_epi8而不是set1之类的一条指令的内在函数

比其内在文档更好/更详细(例如,“操作”部分始终存在,并且通常更为具体)。另外,它还向您显示了操作数的顺序。这通常与内在函数匹配,但是我似乎还记得有这种情况的情况,可能是改组。当然,vfmadd132psvfmadd213psvfmadd231ps的区别在于,加数或被乘数之一是目的地,哪些可以是内存。

它还向您显示哪个操作数可以是内存。它并不总是最后一个,例如VBLENDVPS xmm1, xmm2, xmm3/m128, xmm4(因为最后一个操作数被编码为立即数,而不是像非VEX版本那样被隐式地xmm0编码)。另外,pmovzxbd xmm1, dword [rdi]和其他代码在缩小负载时很有用(因为它小于16个字节,因此不需要对齐),但是您永远不会从仅向其提供__m128i的内在函数中得知这一点。资源。使用_mm_cvtsi32_si128 (int a)之后,编译器无法始终优化为内存操作数。

pblendvb中,非VEX形式为PBLENDVB xmm1, xmm2/m128, <XMM0>,隐式地将XMM0用作混合控制矢量。内在函数也将其隐藏起来,因此,如果您尝试编写pblendvb xmm1, xmm8, xmm7,将会引起混乱的错误。

Agner Fog's asm optimization guide在SIMD上也有一章,其中有一些非常不错的数据移动指令表,这些表对于不同类型的任务很有用。

另请参见SO x86 tag wiki


我发现更容易记住asm助记符;它们更短,并且在命名方面(如大多数情况下,直到AVX ...),像改组与置换之类的怪异差异要少一些。更重要的是,我倾向于从asm的角度考虑,然后编写可让编译器有效编译的内在函数。

CPU延迟/吞吐量/执行端口信息全都是助记符,而不是固有的(Agner Fog的表,instlatx64http://uops.info/),因此您必须知道这些名称才能真正使用级别的性能详细信息,并检查编译器是否对您的代码做得很好,并查看perf record / perf report分析结果,以弄清为什么某个地方存在热点。 >

Intel在其内在函数指南中具有吞吐量/等待时间数字,但没有执行端口,因此您无法知道两条throughtput=1指令是否可以彼此在同一周期中运行,因此它不是很有用