Рассматривает ли два uint8_ts как uint16_t менее эффективно

Предположим, я создал класс, который принял параметр шаблона, равный числу uint8_ts Я хочу соединить вместе в Big int.

Таким образом, я могу создать огромный int, как это:

SizedInt<1000> unspeakablyLargeNumber;  //A 1000 byte number

Теперь возникает вопрос: убиваю ли я свою скорость, используя uint8_ts вместо использования большего встроенного типа.

Например:

SizedInt<2> num1;
uint16_t num2;

Являются num1 а также num2 с той же скоростью, или num2 Быстрее?

2

Решение

Это, несомненно, будет медленнее использовать uint8_t[2] вместо uint16_t,

Возьмите дополнение, например. Для того, чтобы получить uint8_t[2] ускориться до скорости uint16_tкомпилятор должен будет выяснить, как преобразовать логику добавления с переносом и объединить эти многочисленные инструкции в одно более широкое дополнение. Я уверен, что некоторые компиляторы иногда способны на такую ​​оптимизацию, но есть много обстоятельств, которые могут сделать оптимизацию маловероятной или невозможной.

На некоторых архитектурах это применимо даже к загрузке / хранению, так как uint8_t[2] обычно имеет другие требования по выравниванию, чем uint16_t,

Типичные библиотеки bignum, такие как GMP, работать над самыми большими словами, удобными для архитектуры. На x64 это означает использование массива uint64_t вместо массива чего-то меньшего, как uint8_t, Добавление двух 64-битных чисел на современных микропроцессорах довольно быстрое, на самом деле это обычно та же скорость, что и при добавлении двух 8-битных чисел, не говоря уже о зависимости данных, которая вводится при распространении битов переноса через массивы небольших чисел. Эти зависимости данных означают, что вам часто будет добавляться только один элемент вашего массива за такт, поэтому вы хотите, чтобы эти элементы были максимально большими. (На аппаратном уровне существуют специальные приемы, которые позволяют быстро переносить биты переноса по всей 64-разрядной операции, но эти приемы недоступны в программном обеспечении.)

Если вы хотите, вы всегда можете использовать специализацию шаблонов, чтобы выбрать примитивы правильного размера, чтобы получить наиболее экономичные места, которые вы хотите. В противном случае, используя массив uint64_t гораздо более типично.

Если у вас есть выбор, это обычно Лучше всего просто использовать GMP. Части GMP написаны на ассемблере, чтобы сделать bignum-операции намного быстрее, чем они были бы в противном случае.

4

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

Вы можете получить лучшую производительность от больших типов из-за уменьшенных накладных расходов цикла. Однако компромисс здесь — лучшая скорость и меньшая гибкость в выборе размера.

Например, если большинство ваших чисел имеют длину, скажем, 5 байтов, переключитесь на unit_16 потребует дополнительной нагрузки на дополнительный байт. Это означает, что накладные расходы памяти составляют 20%. С другой стороны, если мы говорим о действительно больших числах, скажем, 50 байтов или более, объем памяти будет намного меньше — порядка 2%, поэтому увеличение скорости будет достигаться при гораздо меньших затратах.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector