XMM 寄存器的按位取反

     2023-02-16     260

关键词:

【中文标题】XMM 寄存器的按位取反【英文标题】:Bitwise negation of XMM register 【发布时间】:2016-01-19 16:34:45 【问题描述】:

如何获得 XMM 寄存器中值的按位取反?据我所知,没有这样的指示。唯一带有否定的指令是pandn,但要使用它来简单地否定一个 XMM 寄存器中的值,我必须让另一个 XMM 寄存器填充 1

还有其他方法可以否定 XMM 寄存器中的位吗?或者有没有一种巧妙的方法可以在不访问内存的情况下用1 填充 XMM 寄存器?

【问题讨论】:

【参考方案1】:

要加载一个全为 1 的寄存器,请使用

pcmpeqd xmm0, xmm0

之后你可以简单地从xmm0中减去xmmX得到~xmmX,或者使用pandn

您还可以轻松地将其他常量加载到 xmm 寄存器中

pcmpeqd xmm0, xmm0
psrld   xmm0, 30   ; 3 (32-bit)

pcmpeqd xmm0, xmm0 ; -1

pcmpeqw xmm0, xmm0 ; 1.5f
pslld   xmm0, 24
psrld   xmm0, 2

pcmpeqw xmm0, xmm0 ; -2.0f
pslld   xmm0, 30

阅读 Agner Fog 的优化指南,13.4 Generating constants - Making constants for integer vectors in XMM registers

【讨论】:

...或pxor 与全1寄存器。 psubdpandn 相对于 pxor 的优势为零。 psubd 的吞吐量更差,而且两者都不是可交换的。 Constant floats with SIMD, What are the best instruction sequences to generate vector constants on the fly?【参考方案2】:

pxor 与全1 寄存器一起使用。

pandn 也可以使用,但优势为零。没有任何情况下,pandn 和一个全为常量可以让你做任何你不能用 pxor 做的事情。

psubd 也可用(2 的补码标识),但比pandn 更差,因为它在某些 CPU 上的吞吐量较低(执行端口较少)。


pcmpedq  xmm1, xmm1      ; create the all-ones.  No false dependency.

pxor     xmm0, xmm1      ; flip all the bits in XMM0. Doesn't destroy XMM1
;pandn    xmm0, xmm1      ; equivalent but no advantage.  (~xmm0) & xmm1

PXOR 很好,因为它是可交换的。借助 AVX,您可以使用一个微融合 uop 加载和不加载:

vpxor    xmm0, xmm1, [rdi]

VPANDN 无法做到这一点,因为可以是内存或寄存器的操作数是非反转操作数。 (但是,如果没有 AVX,只需 movdqadqu 加载,然后 pxor 加载结果。reg-copy 和 micro-fused load+pxor 是 3 个未融合域 uops,而 2 个)


或者没有 AVX,如果你想销毁全一常量而不是你正在反转的数据,pxor 再次获胜:

movdqa  xmm2, xmm1      ; copy the all-ones constant.  Off the critical path for latency
pxor    xmm2, xmm0

您可以将movdqamovdqa xmm2, xmm0 / pandn xmm2,xmm1 分开。 (只有 IvyBridge+ 和 Bulldozer-family/Ryzen 对矢量寄存器具有零延迟 movdqa。)或者,如果您每次都在目标寄存器中使用 pcmpeqd 重新实现全1(可能是因为寄存器压力或因为您不要循环执行),这将是另一种情况,您需要 pxor 而不是 pandn


使用pcmpeqb/w/d 生成一个全1 常量是一种特殊情况,不会对旧值产生错误依赖(在 Silvermont 上除外),但仍然需要一个执行单元(与 Sandybridge 上的异或归零不同-家庭)。不过,它很便宜,而且它是编译器用于_mm_set1_epi32(-1) 的。

每次需要时重新创建常量而不是从另一个寄存器复制在 IvyBridge 及更高版本以及 Bulldozer-family 和 Ryzen 上稍微更糟。 XMM 副本的mov-elimination 避免占用向量执行单元/端口,以防向量-ALU 执行端口成为您的瓶颈。

但它在 Intel P6 系列(Core2/Nehalem)上稍好一些:当在一个问题组中读取太多“冷”寄存器时,寄存器读取停顿可能是一个问题。 (参见 Agner Fog 的 microarch pdf https://agner.org/optimize/)。 P6 系列已过时,但仍在一些旧机器中使用。如果您有在带有 AVX 的 CPU 上运行的 AVX 版本,您可能希望在代码的非 AVX 版本中对其进行调整。 (但 Haswell/Skylake “pentium”/“celeron”仍然是一个东西,而且他们没有 AVX,所以没有 AVX 并不意味着旧 CPU。)

【讨论】:

参见 Is NOT missing from SSE, AVX? 了解内在函数,以及 AVX-512F vpernlogd 在没有向量常数的情况下完成工作。

复习一个小知识点(反码与按位取反)

第一点是:反码与按位取反~在Java中~符号是按位取反,例如,~5=-6。-5=4. 快速计算:一般~可以直接用(a+1)算,正数负数均可思路:是按位取反运算,与反码是不同的,反码法规定,正数原反补码相同,负数的反码为原码除符... 查看详情

用异或代替按位求反

...来的每一位,1变0,0变1。按照这个1变0,0变1的标准,若求x的按位取反值,可以用求异或来替代。异或的本质是模二加,效果是相同为1,相异为0。对于x=10101,想要用异或来达到按位取反的效果,就得找出一个特殊的数。令这个数... 查看详情

c#'~'按位取反运算符的使用

按位取反运算符是按照二进制的每一位取反,比如byte类型,~0的结果就是255。该功能可以在mask中做一些反转操作 如下代码,a存放了2,4,8三个值。用按位取反‘~‘运算符反转打印结果是 false,flase,false,true,trueclassProgram{static... 查看详情

按位与,按位或,按位异或,按位取反

...符:是指对二进制位从低位到高位对齐后进行运算。1、按位与& 二进制“与”运算规则:1&1=11&0=00&0=0例如:$n=6;$m=12;$n&$m=???其中;6=二进制 110;12=二进制1100; $n&$m=10 01101100==》0100(二进制)=... 查看详情

java按位运算符之按位取反

一数据储存形式二进制在内存中以补码的形式存在。补码首位是符号位,0表示该数是正数,1表示该数是负数。 例如: 数值带符号的二进制原码(首位表示符号位)补码内存中的形式(*表示无效位,其数量取决于分配的内存空... 查看详情

python进阶练习之——按位取反⚡(代码片段)

**题目:**学习使用按位取反~。**程序分析:**~0=1;~1=0;print(~234)print(~~234)📣小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶📣有什么不明白的欢迎私信或留言,得到细致讲解。另外想要进阶... 查看详情

数据运算

...就是^,正好相反,相同为0,不通为1按位取反运算~,取60的按位取反,就是0变成1,1变成0所以~60=195,但是实际情况呢得到-61,都是负值因为计算机 查看详情

《算法零基础100例》(第51例)按位取反-2

注意:本专栏目前处于规划阶段,目前正在陆续实现中,11月正式推出,请稍作等待。《算法零基础100例》真正的零基础文章目录一、概念定义二、题目描述三、算法详解四、源码剖析五、推荐专栏六、粉丝福利... 查看详情

《算法零基础100例》(第50例)按位取反-1

注意:本专栏目前处于规划阶段,目前正在陆续实现中,11月正式推出,请稍作等待。《算法零基础100例》真正的零基础文章目录一、概念定义二、题目描述三、算法详解四、源码剖析五、推荐专栏六、粉丝福利... 查看详情

《算法零基础100讲》(第50讲)位运算(按位取反)

文章目录零、写在前面一、概念定义1、取反运算符的定义2、取反运算符的应用1)0的取反1.a)有符号整型1.b)无符号整型2)相反数3)代替减法4)代替加法二、题目描述三、算法详解四、源码剖析五、推荐专栏六、习题练习零... 查看详情

补码(为什么按位取反再加一):告诉你一个其实很简单的问题

...查到的资料,然后他们都会很耐心的告诉你,补码:就是按位取反,然后加一。准确无误,毫无破绽。但是,你搜遍了所有俯拾即是而且准确无误的答案,却仍然选择来看这篇毫不起眼的文章,原因只有一个,只因为你还没有得... 查看详情

位运算

位运算符1、 11(00001011)  按位取反    ~11 (11110100)       13(0000 1101) 按位取反    ~13(11110010)2、按位与  查看详情

正负数取反的结果和规律

按位取反运计算方法原创jackytse_最后发布于2012-10-2914:27:01阅读数11247收藏展开读本文前请首先搞懂 “反码”,“取反”,“按位取反(~)”,这3个概念是不一样的。取反:0变1,1变0反码:正数的反码是其本... 查看详情

位运算

...据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。位运算符有:    &(按位与)、|(按位或)、^(按位异或)、~(按位取反)。    其中,按位取反运算... 查看详情

128 位整数之间的按位运算

...】:2013-09-1018:02:37【问题描述】:我有一个关于使用128位寄存器来提高代码速度的问题。考虑以下C/C++代码:我定义了两个unsignedlonglongintsa和b,并给它们一些值。unsignedlonglonginta=4368,b=56480;然后,我要计算a&b;这里a 查看详情

perl操作符

...示+加法-减法*乘法/除法%取余**幂指数位运算符号表示&按位与|按位或^按位异或~按位取反and按位与or按位或xor按位异或not按位取反>>按位右移<<按位左移数值比较运算符符号表示>大于>=大于等于<小于<=小于等于... 查看详情

计算机基础

...p; (异或是要异或符号左右的比较值不一样才为true)2、按位取反当使用~按位取反运算的时候,计算机会将操作数所对应的二进制表达式的每一个位进行取反计算,取反后所得到的值就是~按位取反的运算结果(这点没问题)例... 查看详情

c51较c比较,单片机最小系统

sfr(Specialfunctionregisters):特殊功能寄存器声明bit:位变量声明sbit:特殊位声明psw^2,表示psw寄存器上的第2位<<>>位左移位右移&|按位与,按位或^按位异或~按位取反 单片机最小系统:1.电源2.晶振3.复位电路 查看详情