Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly x86 SSE中四压缩单精度浮点到无符号双字的转换_Assembly_X86 64_Sse_Floating Point Conversion_Sse3 - Fatal编程技术网

Assembly x86 SSE中四压缩单精度浮点到无符号双字的转换

Assembly x86 SSE中四压缩单精度浮点到无符号双字的转换,assembly,x86-64,sse,floating-point-conversion,sse3,Assembly,X86 64,Sse,Floating Point Conversion,Sse3,在x86中,是否有方法使用SSE扩展将四个压缩单精度浮点值转换为四个双字? 最接近的指令应该是CVTPS2PI,但它不能在两个xmm寄存器上执行,而是应指定为CVTPS2PI MM,xmm/M64。如果我想要像XMM,XMM/M128这样的东西怎么办 谢谢。 Iman.x86在使用vcvtps2udq()的AVX512之前不支持FPunsigned。对于标量,您通常只需将其转换为64位有符号(cvtss2si-rax,xmm0)并取其低32位(在EAX中),但SIMD不允许这样做 如果没有AVX

在x86中,是否有方法使用SSE扩展将四个压缩单精度浮点值转换为四个双字? 最接近的指令应该是CVTPS2PI,但它不能在两个xmm寄存器上执行,而是应指定为
CVTPS2PI MM,xmm/M64
。如果我想要像
XMM,XMM/M128这样的东西怎么办

谢谢。
Iman.

x86在使用
vcvtps2udq
()的AVX512之前不支持FPunsigned。对于标量,您通常只需将其转换为64位有符号(
cvtss2si-rax,xmm0
)并取其低32位(在EAX中),但SIMD不允许这样做

如果没有AVX-512,理想情况下,您可以使用有符号转换(
cvtps2dq
)并获得相同的结果。i、 e.如果您的浮动是非负的,并且是uint64\t转换。如果需要的话,全量程应该可以从double->uint64\u t调整到float->uint32\u t

另一种可能性(对于32位浮点->uint32_t)是将范围移到有符号FP,然后返回整数
INT32\u MIN^转换(x+INT32\u MIN)
。但这会为小整数引入FP舍入,因为INT32_MIN在-224之外。。224范围,其中
浮点数可以表示每个整数。e、 g.
5
将在转换过程中四舍五入到28的最接近倍数。所以这是不可用的;您需要尝试直接转换和范围移位转换,并且仅当直接转换为
0x8000000
时才使用范围移位转换。(可能使用直接转换结果作为SSE4的混合控制
blendvps
?)


对于浮点->整数的压缩转换,有SSE2
cvtps2dq xmm,xmm/m128
。(
cvttps2dq
转换时截断为0,而不是当前的默认舍入模式(最近,如果您没有更改它的话)。)

任何小于-0.5的负浮点将转换为整数-1或更低;作为
uint32\t
,该位模式表示一个巨大的数字。超出-231..231-1范围的浮点将转换为
0x8000000
,即英特尔的“不定整数”值


如果您没有找到,只有cvtps2pi签名转换为MMX寄存器,则需要更好的搜索位置:

  • -链接
  • x86指令集列表
  • -按类别/功能列出的说明列表
  • -asm指令助记符是针对仅公开单个指令功能的内部函数列出的。通常情况下,用intrinsic编写C要比手工编写asm好,尤其是如果您还不知道诸如
    cvtps2dq
    cvttps2dq
    等相对普通/简单的指令
  • -他的《asm优化指南》中有一章介绍SIMD,其中包含各种数据移动指令的方便表格
  • -指向正确方向的指针,但仅涵盖有符号转换。我没有找到完全相同的

结果应该是整数类型吗?也许可以试试
cvtps2dq
?谢谢@fuz。cvtps2dq将很好地完成这项工作,但需要四个压缩有符号双字。您知道无符号双字类型的类似指令吗?如果您想要无符号整数,您应该在问题中指定它。另外,您想要什么舍入和溢出行为?谢谢@chtz。舍入:舍入到最接近的整数。溢出:实际上我没有处理大浮点,它们都是正的,所以没关系。如果输入大于
2**31
(除了
cvtps2dq
),你可以从浮点中减去
2**32
。@chtz:减去
2**32
对于大浮点有什么好处,而不是我建议的
INT32\u MIN^convert(x+INT32\u MIN)
?uint32范围的上半部分为
2**31。。2**32-1
,因此减去2^31不会增加任何大于2^31的输入的大小,因此不会进行更多舍入。您不会有任何舍入问题(因为值
=2**31
将映射到
[-2**31,0]中的值
,因此您只需要一次转换。减去
2**32
会自动给出正确的环绕行为,就像进行了无符号转换一样(除非输入大于
UINT32\u MAX
)@chtz:哦,我明白了,
2**32
的整数加法是不可行的。是的,这是个好主意。如果你愿意,我的答案是,或者发表你自己的。我的答案主要集中在当你的数字是非负数且不是很大时,可以使用有符号转换;对于实际工作的全范围转换方法,单独的答案可能是最好的。