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

Inline ntohs() / ntohl() in C++ / Boost ASIO

本文关键字:ntohs ntohl Boost ASIO c++      更新时间:2023-10-16

嗨,我正在使用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()。任何帮助都将非常感激。

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

x86-32和x86-64平台有一个32位的'bswap'汇编指令。我认为你只能做一次手术。

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

看汇编程序,__imp__ntohl@4是一个来自DLL的导入符号,所以它是一个外部函数,不能内联。

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

你可以找到几个高度优化的版本或多或少可移植的版本在gtypes.h头从glib,宏GUINT32_SWAP_LE_BE:glib.h

请参阅优化字节交换的乐趣和利润。它解释了如何使它快速。

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