Arhn - архитектура программирования

Целые числа Word и Double Word в C

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

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

Спасибо!


  • по какой причине вы не хотите использовать существующую и хорошо протестированную библиотеку? 10.01.2010
  • Митч: в основном это просто упражнение для меня, чтобы освежить мой C. 10.01.2010
  • С GCC в системе x86_64 вы можете использовать тип __int128_t для выполнения 128-битных целочисленных арифметических операций. Однако это не портативно. 10.01.2010
  • Делая то же самое в Java несколько лет назад, который также не поддерживает asm для проверки битов, было значительно эффективнее представлять 31 или 63 бита внутри, чем расширять при использовании. GMP имеет экспериментальную поддержку «гвоздей», что похоже на аналогичный подход. 10.01.2010
  • Пит, я думаю, вам следует добавить этот комментарий как фактический ответ (к части обнаружения переполнения). 11.01.2010

Ответы:


1

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

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

10.01.2010
  • У меня сложилось впечатление, что intptr_t для этой цели немного более переносим, ​​чем size_t: sizet-vs-intptrt Конечно, я не собираюсь хранить указатели, я хочу хранить целое число, занимающее целый регистр. 10.01.2010
  • @datkin: Вопрос в вашей ссылке конкретно о хранении указателей. В вашем случае size_t лучше, чем intptr_t, или используйте типы [u]int[_fast]N_t. 10.01.2010
  • Я знаю, что это просто упражнение, но насколько важна переносимость? Если это не важно, то, возможно, вы не заботитесь о size_t. Также у меня были проблемы с использованием size_t в #define. 11.01.2010

  • 2

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

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

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

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

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

    10.01.2010
  • Проблема в том, что я бы хотел, чтобы цифры сохранялись с использованием int32_t на 32-битных машинах и int64_t на 64-битных машинах. Является ли следующий способ сделать это лучше, чем использование типа intptr_t?: #if __WORDSIZE == 64 typedef int64_t intword_t #else typedef int32_t intword_t #endif Кроме того, на 32-разрядной машине я всегда могу преобразовать int32_t в int64_t, чтобы гарантировать кроме того, и т. д. не переполняется, однако на 64-битной машине есть ли 128-битный тип, к которому я могу повысить, чтобы избежать переполнения? 10.01.2010
  • C99 определяет int_fast64_t, int_fast32_t и т. д. Так что, может быть, они будут полезны? Поскольку ваша цель — реализовать умеренно эффективную библиотеку, я бы посоветовал использовать одну из вышеперечисленных, а затем оптимизировать позже по мере необходимости. 10.01.2010
  • Насколько я понимаю, типы int_fastXX_t просто псевдоним любого естественного типа int для вашей машины (за исключением случаев, когда XX больше, чем собственная ширина int вашей машины). Таким образом, int_fast8_t будет 32-битным на 32-битной машине и 64-битным на 64-битной машине. Предоставляют ли эти типы другие оптимизации или это все? 10.01.2010
  • @datkin, да: int_fast32_t на самом деле может быть int64_t. Но они не обеспечивают никакой другой оптимизации. Причина, по которой я предложил это, потому что вы упомянули оптимизацию в своем первоначальном вопросе. В любом случае, поскольку вы просто пробуете, вам следует выбрать один тип, а затем оптимизировать его позже. 10.01.2010
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..