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

2019-05-11 01:27发布

Hi I'm using C++ / Boost ASIO and I have to inline ntohl() for performance reasons. Each data packet contains 256 int32s, hence a lot of calls to ntohl(). Has anyone done this?

Here is the compiled assembly output out of VC10++ with all optimizations turned on:

;  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

I've also tried the regular ntohl() provided by winsock. Any help would be greatly appreciated.

Also, I've been thinking the C way of having a #define macro that does simple int32 barrel shifts (if the network order doesn't match the machines order at compile time). And if anyone knows and can provide the most efficient assembly for ntohl() on a x86 / x64 architecture, that would be awesome. Eventually my code needs to be portable to ARM as well.

3条回答
唯我独甜
2楼-- · 2019-05-11 01:44

Looking at the assembler, __imp__ntohl@4 is an import symbol from a DLL, so it is an external function and cannot be inlined.

Of course you can write your own, even macro, knowing that you are most likely using Windows in a little-endian machine, you just need to swap bytes.

You can find several highly optimized versions more or less portable version in the gtypes.h header from glib, macro GUINT32_SWAP_LE_BE: glib.h

查看更多
\"骚年 ilove
3楼-- · 2019-05-11 01:57

Please see optimizing byte swapping for fun and profit. It explains how to make it fast.

But I strongly recommend you stop worrying about it. Think about it - ASIO is allocating a memory to store handler's state every time you call async_read, just for example. That is by far more expensive than calling innocent ntohl, which is inlined in Linux by default, by the way. It seems like you have a premature optimization problem - you should stop that immediately, or you will waste your time and resources. After all - profile your application first, then optimize it (vTune or TotalView is recommended).

查看更多
够拽才男人
4楼-- · 2019-05-11 02:01

The x86-32 and x86-64 platforms have a 32-bit 'bswap' assembly instruction. I don't think you'll do better than one operation.

uint32_t asm_ntohl(uint32_t a)
{
   __asm
    {
       mov eax, a;
       bswap eax; 
    }
}
查看更多
登录 后发表回答