assembly - 将单个字节从内存移动到 xmm 寄存器作为浮点数
问题描述
如何从内存中的地址检索单个字节并将其值作为浮点数移动到 xmm 寄存器中?(例如,如果地址位置有一个字节 123,我希望能够使用 sse 指令对这个值进行浮点运算,例如 123+5 等。)
我是组装新手,我希望这个问题是有道理的。我已经相当随机地尝试了几件事(例如al
从那里移到第一个并移到 xmm - 但不知道如何继续转换为浮点数......);也许有人可以指出我正确的方向?
解决方案
显而易见的标量方式,就像您从编译器 ( http://godbolt.org/ ) 中获得的那样:
movzx eax, byte [mem] ; zero extend. Use movsx to sign-extend
cvtsi2ss xmm0, eax
这在 Sandybridge-family 上总共花费了 3 微秒。(cvtsi2ss
是 2)。
请注意,cvtsi2ss
它的设计很差,并合并到 XMM0 的旧值中,因此它具有错误的依赖关系。gcc 倾向于pxor xmm0,xmm0
首先打破依赖关系,但如果 XMM0 最近没有使用,那么你应该没问题。使用 AVX,您可以将一个 XMM 寄存器归零,然后重复将其用作多个转换的安全无依赖源。
vxorps xmm0, xmm0, xmm0
;then repeated multiple times:
vcvtsi2ss xmm1, xmm0, eax ; xmm1 is write-only, no false dep
如果 SSE4.1 可用,并且可以读取超过所需字节的 3 个字节(不会因读取未映射的页面而出现段错误,也不会因缓存行或页面拆分而出现性能问题),那么您可以这样做:
pmovzxbd xmm0, dword [mem] ; byte->dword packed zero extend
cvtdq2ps xmm1, xmm0 ; packed-convert of int32 to float
这在 SnB 系列上总共花费 2 个微指令:pmovzx/sx
使用 XMM 目标可以微熔断负载。(但不是 AVX2 YMM 版本)。(http://agner.org/optimize/)。
当然,如果您真的想转换 4 个连续字节,这非常好。cvt
否则,如果您有多次转换,您可能会随机设置指令。
推荐阅读
- mysql - 将列值与另一个没有公共列的表匹配
- javascript - Angular 6:async await some variable got it variable
- stripe-payments - 我想在单个平台上集成 Square API 和 Stripe API,两者的功能应该相同,下面是我无法找到答案的查询
- shell - 当提示宽度与 COLUMNS 相同时,zsh 会截断先前的标准输出
- spring - 如何通知不同用户的工作状态变化?
- sqlbase - SqlBase 和 Gupta 窗户通向天空
- android - GridView 项目颜色在选择时发生变化,之前选择的项目应显示其他颜色
- javascript - 显示第一个 JSON 数据对象而不使用 Angular JS 选择任何链接
- c# - 等效于 inline out 参数声明?
- vba - 访问 VBA - 将日期变量从函数传递到子