c++ / Boost ASIO中的内联ntohs() / ntohl()
Inline ntohs() / ntohl() in C++ / Boost ASIO
嗨,我正在使用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)。