Слова и двойные слова в C - PullRequest
1 голос
/ 10 января 2010

Я пытаюсь реализовать простую, умеренно эффективную библиотеку bignum на C. Я хотел бы хранить цифры, используя полный размер регистра системы, на которой она скомпилирована (предположительно, 32 или 64-битные числа). Насколько я понимаю, я могу сделать это с помощью intptr_t. Это правильно? Существует ли более семантически подходящий тип, например, intword_t?

Я также знаю, что с помощью GCC я легко могу обнаружить переполнение на 32-разрядной машине, переведя оба аргумента в 64-разрядные числа, которые будут занимать два регистра и использовать такие инструкции, как IA31 ADC (добавьте с переносом). Могу ли я сделать что-то подобное на 64-битной машине? Есть ли 128-битный тип, который я могу выгрузить, который будет компилироваться, чтобы использовать эти инструкции, если они доступны? А еще лучше, есть ли стандартный тип, который представляет вдвое больший размер регистра (например, intdoubleptr_t), так что это можно сделать независимо от машины?

Спасибо!

Ответы [ 2 ]

1 голос
/ 10 января 2010

Есть причина не использовать size_t? size_t составляет 4 байта в 32-битной системе и 8 байтов в 64-битной системе и, вероятно, более переносим, ​​чем использование WORD_SIZE (я думаю, что WORD_SIZE зависит от gcc, нет?)

Мне не известно о каком-либо 128-битном значении в 64-битных системах, я могу ошибаться, но не встречал такого типа в ядре или в обычных пользовательских приложениях.

1 голос
/ 10 января 2010

Я настоятельно рекомендую использовать заголовок C99 <stdint.h>. Он объявляет int32_t, int64_t, uint32_t и uint64_t, которые выглядят как то, что вы действительно хотите использовать.

РЕДАКТИРОВАТЬ: Как указывает Алок, int_fast32_t, int_fast64_t и т. Д., Вероятно, то, что вы хотите использовать. Количество битов, которое вы указываете, должно быть минимально необходимым для работы математики, т. Е. Чтобы вычисление не переворачивалось.

Оптимизация происходит из-за того, что ЦПУ не нужно тратить циклы на переупорядочение данных, заполнение начальных битов при чтении и выполнение чтения-изменения-записи при записи. По правде говоря, многие процессоры (такие как последние x86) имеют аппаратное обеспечение в ЦП, которое довольно хорошо оптимизирует этот доступ (по крайней мере, части заполнения и чтения-изменения-записи), поскольку они настолько распространены и обычно включают в себя только передачу между процессор и кеш.

Таким образом, единственное, что вам остается сделать, это убедиться, что доступы выровнены: возьмите sizeof(int_fast32_t) или что-то еще и используйте его, чтобы убедиться, что ваши буферные указатели выровнены по этому.

Правда в том, что это может не означать такого большого улучшения (поскольку аппаратная оптимизация во время выполнения все равно оптимизирует передачу), поэтому запись чего-либо и синхронизация могут быть единственным способом убедиться в этом. Кроме того, если вы действительно помешаны на производительности, вам, возможно, придется взглянуть на SSE или AltiVec или любую другую технологию векторизации, которую использует ваш процессор, поскольку она превзойдет все, что вы можете написать, переносимо при выполнении векторной математики.

...