Как функции ntoh реализованы в RHEL / GCC?

Производственный вопрос привел нашу команду к следующим вопросам:

  1. Под RHEL6, используя GCC 4.4.6, как ntohs а также ntohl реализованы?
  2. Известно ли, что реализации бывают быстрыми или медленными?
  3. Как я могу увидеть сгенерированный ассемблерный код для функций?

Я знаю, что последствия вопросов могут показаться надуманными и нелепыми, но меня попросили провести расследование.

Это аппаратное обеспечение Intel, 64-битный процессор с прямым порядком байтов и скомпилированное в 64-битной версии.

6

Решение

  1. Они предоставляются Glibc, а не GCC, посмотрите в /usr/include/bits/byteswap.h для __bswap_16 а также __bswap_32 функции, которые используются при включенной оптимизации (см. <netinet/in.h> для деталей как.)
  2. Вы не сказали, какую архитектуру вы используете, в системе с прямым порядком байтов они не используются, так что оптимально быстро! На little-endian они представляют собой сборочный код, оптимизированный вручную для конкретной архитектуры.
  3. Используйте GCC -save-temps возможность сохранить промежуточное .s файлы или использовать -S остановить после компиляции и перед сборкой кода, или использовать http://gcc.godbolt.org/
11

Другие решения

Сделайте следующее:

test.c

#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)

подсказки:

  • 305419896 — это 0x12345678 в десятичном виде.
  • 12(%esp) адрес переменной переменной.
  • Все movl инструкции есть для volatile-нессность x, Единственная действительно интересная инструкция bswap,
  • Очевидно, что ntohl составляется как встроенный-встроенный.

Более того, если я посмотрю на test.i (предварительно скомпилированный вывод), я считаю, что ntohl является #defined так же просто __bswap_32(), которая является встроенной функцией только с вызовом __builtin_bswap32(),

12

Они реализованы в glibc. Посмотрите на /usr/include/netinet/in.h. Скорее всего, они будут полагаться на макросы glibc byteswap (/usr/include/bits/byteswap.h на моей машине)

Они реализованы в сборке в моем заголовке, поэтому должны быть довольно быстрыми. Для констант это делается во время компиляции.

7

GCC / glibc заставляет ntohl () и htonl () быть встроенными в вызывающий код. Следовательно, избегаются накладные расходы при вызове функции. Кроме того, каждый вызов ntohl () или htonl () транслируется в одну операцию ассемблера bswap. Согласно «Справочному руководству по оптимизации архитектур Intel® 64 и IA-32» bswap имеет задержку и пропускную способность «1» для всех текущих процессоров Intel. Таким образом, для выполнения ntohl () или htonl () требуется только один такт процессора.

ntohs () и htons () представлены в виде поворота на 8 бит. Это эффективно заменяет две половины 16-битного операнда. Задержка и пропускная способность аналогичны bswap.

1
По вопросам рекламы [email protected]