Производственный вопрос привел нашу команду к следующим вопросам:
ntohs
а также ntohl
реализованы?Я знаю, что последствия вопросов могут показаться надуманными и нелепыми, но меня попросили провести расследование.
Это аппаратное обеспечение Intel, 64-битный процессор с прямым порядком байтов и скомпилированное в 64-битной версии.
/usr/include/bits/byteswap.h
для __bswap_16
а также __bswap_32
функции, которые используются при включенной оптимизации (см. <netinet/in.h>
для деталей как.)-save-temps
возможность сохранить промежуточное .s
файлы или использовать -S
остановить после компиляции и перед сборкой кода, или использовать http://gcc.godbolt.org/Сделайте следующее:
#include <arpa/inet.h>
int main()
{
volatile uint32_t x = 0x12345678;
x = ntohl(x);
return 0;
}
Затем скомпилируйте с:
$ gcc -O3 -g -save-temps test.c
И проанализировать полученный test.s
файл или альтернативно запустить objdump -S test.o
,
В моей машине (Ubuntu 13.4) соответствующий ассемблер:
movl $305419896, 12(%esp)
movl 12(%esp), %eax
bswap %eax
movl %eax, 12(%esp)
подсказки:
12(%esp)
адрес переменной переменной.movl
инструкции есть для volatile
-нессность x
, Единственная действительно интересная инструкция bswap
,ntohl
составляется как встроенный-встроенный.Более того, если я посмотрю на test.i
(предварительно скомпилированный вывод), я считаю, что ntohl
является #defined
так же просто __bswap_32()
, которая является встроенной функцией только с вызовом __builtin_bswap32()
,
Они реализованы в glibc. Посмотрите на /usr/include/netinet/in.h. Скорее всего, они будут полагаться на макросы glibc byteswap (/usr/include/bits/byteswap.h на моей машине)
Они реализованы в сборке в моем заголовке, поэтому должны быть довольно быстрыми. Для констант это делается во время компиляции.
GCC / glibc заставляет ntohl () и htonl () быть встроенными в вызывающий код. Следовательно, избегаются накладные расходы при вызове функции. Кроме того, каждый вызов ntohl () или htonl () транслируется в одну операцию ассемблера bswap. Согласно «Справочному руководству по оптимизации архитектур Intel® 64 и IA-32» bswap имеет задержку и пропускную способность «1» для всех текущих процессоров Intel. Таким образом, для выполнения ntohl () или htonl () требуется только один такт процессора.
ntohs () и htons () представлены в виде поворота на 8 бит. Это эффективно заменяет две половины 16-битного операнда. Задержка и пропускная способность аналогичны bswap.