什么是反转16位和32位整数的字节顺序的最快方法。 我经常做类似的事情(这个编码是在C ++的Visual Studio中完成的):
union bytes4 { __int32 value; char ch[4]; }; union bytes2 { __int16 value; char ch[2]; }; __int16 changeEndianness16(__int16 val) { bytes2 temp; temp.value=val; char x= temp.ch[0]; temp.ch[0]=temp.ch[1]; temp.ch[1]=x; return temp.value; } __int32 changeEndianness32(__int32 val) { bytes4 temp; temp.value=val; char x; x= temp.ch[0]; temp.ch[0]=temp.ch[1]; temp.ch[1]=x; x= temp.ch[2]; temp.ch[2]=temp.ch[3]; temp.ch[3]=x; return temp.value; }
有没有更快的方法来做同样的事情,我不需要做那么多的计算?
你为什么不使用内置的swab
function,它可能比你的代码优化得更好?
除此之外,通常的位移操作应该很快开始,并且如此广泛使用它们可以被优化器识别并被更好的代码所取代。
因为其他答案有严重的错误,我会发布一个更好的实现:
int16_t changeEndianness16(int16_t val) { return (val << 8) | // left-shift always fills with zeros ((val >> 8) & 0x00ff); // right-shift sign-extends, so force to zero }
我测试的所有编译器都没有为这段代码生成rolw
,我认为稍长的序列(就指令数而言)实际上更快。 基准会很有趣。
对于32位,有几个可能的操作订单:
//version 1 int32_t changeEndianness32(int32_t val) { return (val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | ((val >> 24) & 0x000000ff); } //version 2, one less OR, but has data dependencies int32_t changeEndianness32(int32_t val) { int32_t tmp = (val << 16) | ((val >> 16) & 0x00ffff); return ((tmp >> 8) & 0x00ff00ff) | ((tmp & 0x00ff00ff) << 8); }
至少在Visual C ++中,您可以使用_byteswap_ulong()和朋友: http : //msdn.microsoft.com/en-us/library/a3140177.aspx
这些函数被VC ++编译器视为内在函数,并将导致生成的代码在可用时利用硬件支持。 使用VC ++ 10.0 SP1,我看到以下为x86生成的代码:
return _byteswap_ulong(val); mov eax, DWORD PTR _val$[esp-4] bswap eax ret 0 return _byteswap_ushort(val); mov ax, WORD PTR _val$[esp-4] mov ch, al mov cl, ah mov ax, cx ret 0
谁说它做了太多计算?
out = changeEndianness16(in); gcc 4.6.0 movzwl -4(%rsp), %edx movl %edx, %eax movsbl %dh, %ecx movb %cl, %al movb %dl, %ah movw %ax, -2(%rsp) clang++ 2.9 movw -2(%rsp), %ax rolw $8, %ax movw %ax, -4(%rsp) Intel C/C++ 11.1 movzwl 4(%rsp), %ecx rolw $8, %cx xorl %eax, %eax movw %cx, 6(%rsp)
你的编译器产生了什么?
我使用以下代码进行16位版本交换function:
_int16 changeEndianness16(__int16 val) { return ((val & 0x00ff) << 8) | ((val & 0xff00) >> 8); }
用g ++(Ubuntu / Linaro 4.4.4-14ubuntu5)4.4.5上面的代码用g++ -O3 -S -fomit-frame-pointer test.cpp
得到以下(非内联)汇编代码:
movzwl 4(%esp), %eax rolw $8, %ax ret
下一个代码是等效的,但是g ++不如优化它。
__int16 changeEndianness16_2(__int16 val) { return ((val & 0xff) << 8) | (val >> 8); }
编译它会提供更多asm代码:
需要了解更多c/c++开发分享更改字节序的最快方法,也可以关注C/ C++技术分享栏目---计算机技术网(www.ctvol.com)!
movzwl 4(%esp), %edx movl %edx, %eax sarl $8, %eax sall $8, %edx orl %edx, %eax ret
以上就是c/c++开发分享更改字节序的最快方法相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979348.html