C ++ / Boost ASIO中的内联ntohs()/ ntohl()

时间:2011-09-21 19:18:49

标签: c++ inline boost-asio endianness

您好我正在使用C ++ / Boost ASIO,出于性能原因,我必须内联ntohl()。每个数据包包含256个int32,因此对ntohl()进行了大量调用。有没有人这样做过?

以下是VC10 ++中已编译的程序集输出,其中所有优化都已打开:

;  int32_t d = boost::asio::detail::socket_ops::network_to_host_long(*pdw++);
mov      esi, DWORD PTR _pdw$[esp+64]
mov      eax, DWORD PTR [esi]
push     eax
call     DWORD PTR __imp__ntohl@4

我也尝试过winsock提供的常规ntohl()。任何帮助将不胜感激。

另外,我一直在考虑使用#define宏进行简单int32桶移位的C方式(如果网络顺序与编译时的机器顺序不匹配)。如果有人知道并且可以在x86 / x64架构上为ntohl()提供最有效的程序集,那就太棒了。最终我的代码也需要移植到ARM。

3 个答案:

答案 0 :(得分:5)

x86-32和x86-64平台有一个32位的'bswap'汇编指令。我不认为你会比一次手术更好。

uint32_t asm_ntohl(uint32_t a)
{
   __asm
    {
       mov eax, a;
       bswap eax; 
    }
}

答案 1 :(得分:1)

查看汇编程序,__imp__ntohl@4是DLL的导入符号,因此它是一个外部函数,无法内联。

当然你可以编写自己的,甚至宏,知道你最有可能在小端机器上使用Windows,你只需要交换字节。

您可以在glib,gtypes.h的{​​{1}}标题中找到几个高度优化的版本或多或少的可移植版本: glib.h

答案 2 :(得分:1)

请参阅optimizing byte swapping for fun and profit。它解释了如何使它快速。

但我强烈建议你不要担心它。想想看 - 每次调用async_read时,ASIO都会分配一个内存来存储处理程序的状态,例如。这比调用无辜的ntohl要昂贵得多,顺便说一下,默认情况下在Linux中也是如此。看起来你有一个过早的优化问题 - 你应该立即停止,否则你将浪费你的时间和资源。毕竟 - 首先配置您的应用程序,然后优化它(建议使用vTune或TotalView)。