Подтвердить что ты не робот

В чем разница между intXX_t и int_fastXX_t?

Недавно я обнаружил существование стандартного самого быстрого типа, главным образом int_fast32_t и int_fast64_t.

Мне всегда говорили, что для нормального использования в основной архитектуре лучше использовать классический int и long, который всегда должен соответствовать размеру чтения по умолчанию процессора и избегать ненужных числовых преобразований.

В стандарте C99 говорится в §7.18.1.3p2:

"Имя typedef int_fastN_t обозначает наивысший тип целочисленного знака с шириной не менее N. Имя typedef uint_fastN_t обозначает самый быстрый целочисленный тип без знака с шириной не менее N."

И есть также цитата об этом в §7.18.1.3p1:

"Назначенный тип не гарантированно будет самым быстрым для всех целей, если в реализации нет четких оснований для выбора одного типа над другим, он просто выберет некоторый целочисленный тип, удовлетворяющий требованиям подписности и ширины".

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

Я немного поработал над этим и обнаружил, что некоторые открывают источник изменили некоторые свои функции, но не все из них. Они действительно не объяснили, почему они изменили часть и только часть их кода.

Знаете ли вы, каковы конкретные случаи/обычаи, когда int_fastXX_t действительно быстрее классических?

4b9b3361

Ответ 1

В стандарте C99, 7.18.1.3 Самые быстрые целые числа минимальной ширины.

(7.18.1.3p1) "Каждый из следующих типов обозначает целочисленный тип, который обычно является самым быстрым225) для работы со всеми целыми типами, которые имеют как минимум указанную ширину."

225) "Назначенный тип не гарантированно будет самым быстрым для всех целей, если в реализации нет четких оснований для выбора одного типа над другим, он просто выберет некоторый целочисленный тип, удовлетворяющий требованиям подписи и ширины".

и

(7.18.1.3p2) "Имя typedef int_fastN_t обозначает самый быстрый целочисленный тип со знаком шириной не менее N. Имя typedef uint_fastN_t обозначает самое быстрое целое без знака типа с шириной не менее N."

Типы int_fastN_t и uint_fastN_t являются аналогами целых чисел точной ширины intN_t и uintN_t. Реализация гарантирует, что они принимают не менее N бит, но реализация может принимать больше битов, если она может выполнять оптимизацию с использованием более крупных типов; он просто гарантирует, что они принимают не менее N бит.

Например, на 32-битной машине uint_fast16_t можно определить как unsigned int, а не как unsigned short, потому что работа с типами размера машинного слова будет более эффективной.

Еще одна причина их существования - точные целые типы полной ширины являются необязательными в C, но требуются самые быстрые целые типы минимальной ширины и целые типы минимальной ширины (int_leastN_t и uint_leastN_t).

Ответ 2

Вероятно, не будет никакой разницы, кроме как на экзотическом оборудовании, где int32_t и int16_t даже не существуют.

В этом случае вы можете использовать int_least16_t для получения наименьшего типа, который может содержать 16 бит. Может быть важно, если вы хотите сохранить пространство.

С другой стороны, использование int_fast16_t может привести к вам другому типу, большему, чем int_least16_t, но, возможно, быстрее для "типичного" целого использования. Реализация должна будет учитывать, что быстрее и что типично. Возможно, это очевидно для некоторых аппаратных средств специального назначения?

На большинстве распространенных машин эти 16-битные типы будут типичными для short, и вам не нужно беспокоиться.

Ответ 3

Gnu libc определяет {int, uint} _fast {16,32} _t как 64-разрядный при компиляции для 64-разрядных ЦП и 32-бит в противном случае. Операции над 64-битными целыми числами быстрее на процессорах Intel и AMD 64-разрядных x86, чем те же операции с 32-разрядными целыми числами.

Ответ 4

ИМО они довольно бессмысленны.

Компилятору все равно, что вы называете типом, только какой размер и какие правила применимы к нему. поэтому, если int, in32_t и int_fast32_t - все 32 бита на вашей платформе, они почти наверняка будут работать одинаково.

Теория состоит в том, что разработчики языка должны выбирать на основе того, что является самым быстрым на их оборудовании, но стандартные авторы никогда не закрепляли четкое определение самого быстрого. Добавьте это к тому, что разработчики платформы не хотят изменять определение таких типов (поскольку это будет разрыв ABI), и определения в конечном итоге произвольно выбираются в начале жизни платформ (или унаследованы от других платформ, библиотека C была портирован с) и никогда не касался снова.

Если вы находитесь на уровне микро-оптимизации, что, по вашему мнению, переменный размер может существенно повлиять, сравните различные варианты с вашим кодом на вашем процессоре. В противном случае не беспокойтесь об этом. "Быстрые" типы не добавляют ничего полезного ИМО.