Встроенный ntohs () / ntohl () в C ++ / Boost ASIO - PullRequest
3 голосов
/ 21 сентября 2011

Привет, я использую C ++ / Boost ASIO, и мне нужно встроить ntohl() по соображениям производительности. Каждый пакет данных содержит 256 int32s, следовательно, много вызовов 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

Я также попробовал обычный ntohl(), предоставленный winsock. Любая помощь будет принята с благодарностью.

Кроме того, я думал о способе C иметь макрос #define, который выполняет простые сдвиги int32 (если сетевой порядок не соответствует порядку машин во время компиляции). И если кто-нибудь знает и может предоставить наиболее эффективную сборку для ntohl() на архитектуре x86 / x64, это было бы здорово. В конце концов, мой код должен быть переносимым на ARM.

Ответы [ 3 ]

5 голосов
/ 21 сентября 2011

Платформы x86-32 и x86-64 имеют 32-битную инструкцию по сборке 'bswap'. Я не думаю, что вы сделаете лучше, чем одна операция.

uint32_t asm_ntohl(uint32_t a)
{
   __asm
    {
       mov eax, a;
       bswap eax; 
    }
}
1 голос
/ 21 сентября 2011

Пожалуйста, смотрите оптимизация обмена байтов для удовольствия и прибыли .Это объясняет, как сделать это быстро.

Но я настоятельно рекомендую вам перестать беспокоиться об этом.Подумайте об этом - ASIO выделяет память для хранения состояния обработчика каждый раз, когда вы вызываете async_read, например.Это намного дороже, чем вызов innocent ntohl, который, кстати, встроен в Linux по умолчанию.Похоже, что у вас есть преждевременная проблема оптимизации - вы должны немедленно прекратить это, иначе вы будете тратить свое время и ресурсы.В конце концов - сначала профилируйте приложение, а затем оптимизируйте его (рекомендуется vTune или TotalView).

1 голос
/ 21 сентября 2011

Глядя на ассемблер, __imp__ntohl@4 - это символ импорта из DLL, поэтому он является внешней функцией и не может быть встроен.

Конечно, вы можете написать свой собственный, даже макрос, зная, что выСкорее всего, Windows используется на машине с прямым порядком байтов, вам просто нужно поменять местами байты.

В заголовке gtypes.h от glib, macro GUINT32_SWAP_LE_BE вы можете найти несколько высокооптимизированных версий, более или менее портативных.: glib.h

...