Що таке uint_fast32_t і чому його слід використовувати замість звичайних int та uint32_t?


109

Отже, причина typedef: ed примітивних типів даних полягає в тому, щоб абстрагувати представництво низького рівня та полегшити його розуміння ( uint64_tзамість long longтипу, який становить 8 байт).

Однак є те, uint_fast32_tщо має те саме typedef, що uint32_t. Чи буде використання «швидкої» версії програму швидше?


довга довга може бути не 8 байт, можна мати довгу довгу з 1 байтом (якщо CHAR_BIT становить принаймні 64) або з 3738383 байтами. також uint64_t може бути 1,2,4 або 8 байт, CHAR_BIT має бути 64, 3, 16 або 8 для цього.
12431234123412341234123

Відповіді:


134
  • intна деяких платформах може бути 16 біт. Це може бути недостатньо для вашої заявки.
  • uint32_tне гарантується існування. Необов'язково, typedefщо реалізація повинна забезпечувати, якщо вона має непідписаний цілочисельний тип, рівно 32-бітний. У деяких є, наприклад, 9-бітні байти, тому вони не мають uint32_t.
  • uint_fast32_tчітко заявляє про свій намір: це тип щонайменше 32 біт, який найкращий з точки зору продуктивності. uint_fast32_tнасправді може бути 64 біта. Це до реалізації.

... є те, uint_fast32_tщо має той же типdedef, як uint32_t...

Те, що ви дивитесь, не є стандартом. Це особлива реалізація (BlackBerry). Тож ви не можете вивести звідти uint_fast32_tзавжди те саме, що uint32_t.

Дивитися також:


35
Хороша відповідь. Для повноти можна, можливо, вказати і на різницю uint_least32_t, яка є такою ж, як, uint_fast32_tза винятком того, що вона сприяє меншому магазину, а не швидкості.
Деймон

2
Чому найшвидше ціле число, яке має принаймні 32-бітну ширину, бути більшим, ніж 32-бітове? Я завжди думав, що якщо менше біт, буде менше бітів, з якими повинен працювати процесор, тим самим швидше. Що я тут пропускаю?
Шейн Хсу

12
@ShaneHsu: скажімо, 64-бітний процесор матиме 64-бітове літо, яке підсумовує 64-бітні числа за один цикл. Не має значення, якщо все, що ви хочете зробити, це працювати над 32-бітовими числами, це не буде швидше, ніж один цикл. Тепер, хоча це не так у x86 / amd64, 32-бітні цілі числа можуть бути навіть не адресованими. У такому випадку для роботи над ними потрібні додаткові операційні можливості, щоб витягти 32-бітові з, скажімо, 64-бітових вирівняних одиниць. Дивіться також пов'язане питання. Стандарт C ++ написаний так, що він міг працювати на машині, яка має 37-бітні слова ... тому 32-бітного типу там взагалі немає.
Яків Галка

42

Різниця полягає в їх точності та доступності.

Док тут говорить:

цілий цілей без підпису з шириною рівно 8, 16, 32 та 64 біт відповідно ( надається лише в тому випадку, якщо реалізація безпосередньо підтримує тип ):

uint8_t
uint16_t
uint32_t
uint64_t

І

найшвидший безпідписаний цілий цілий тип із шириною принаймні 8, 16, 32 та 64 біт відповідно

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

Таким чином, різниця майже зрозуміла, що uint32_tце тип, який має саме 32 біти, і реалізація повинна забезпечувати його лише у тому випадку, якщо він має тип з точно 32 бітами, і тоді він може вводити тип цього типу uint32_t. Це означає, що uint32_tможе бути або не бути доступним .

З іншого боку, uint_fast32_tце тип, який має щонайменше 32 біта, що також означає, що якщо реалізація може набратиdef так, uint32_tяк uint_fast32_t ніби вона надає uint32_t. Якщо він не надає uint32_t, то uint_fast32_tможе бути typedef будь-якого типу, який має принаймні 32біт.


3
Але яка причина, що робить, наприклад, uint_fast32_t швидше, ніж uint32_t? Чому це швидше?
Деструктор

2
@PravasiMeet: Не всі цілі числа доступні однаково. До деяких легше отримати доступ, ніж до інших. Легше означає менш обчислювані, більш прямі, що призводить до швидшого доступу. Зараз uint32_tце рівно 32-розрядна версія для всіх систем (якщо вона існує), що може бути не швидше порівняно з тією, яка має, скажімо, 64-бітну. uint_fast32_tз іншого боку, принаймні 32 біт, може бути навіть 64-розрядний.
Наваз

10
@Destructor: У деяких процесорах, якщо змінна зберігається в реєстрі, який довший, компілятору, можливо, доведеться додати додатковий код, щоб зняти зайві біти. Наприклад, якщо uint16_t x;він зберігається в 32-розрядному регістрі в ARM7-TDMI, код x++;може знадобитися оцінити як x=((x+1)<<16)>>16);. На компіляторах для цієї платформи, uint_fast16_tшвидше за все, буде визначено як синонім, uint32_tщоб уникнути цього.
supercat

чому вони [u]int_(fast|least)N_tтакож не є необов'язковими? Напевно, не всі архітектури вимагають стандарту для підтримки примітивних типів принаймні 64 біт? І все ж формулювання stdint.hозначає, що вони повинні. Мені здається дивним, що ми застосовуємо те, що з 1999 року, за кілька років до того, як 64-розрядні обчислення стали основними - нічого не сказати про відставання від (в багатьох випадках досі актуального) вбудованих архітектур. Мені це здається великим недоглядом.
підкреслюй_d

1
@underscore_d: Немає жодної конкретної причини, наприклад, що Стандарт не може бути застосований до реалізації PIC12 з 16 байтами оперативної пам’яті даних та простором для 256 інструкцій. Така реалізація потребує відхилення багатьох програм, але це не повинно заважати їй вести себе визначеним чином для програм, чиї потреби вони могли б задовольнити.
supercat

4

Коли ви перебуваєте #include inttypes.hу своїй програмі, ви отримуєте доступ до безлічі різних способів представлення цілих чисел.

Тип uint_fast * _t просто визначає найшвидший тип представлення заданої кількості бітів.

Подумайте про це так: ви визначаєте змінну типу shortі кілька разів використовуєте її в програмі, що цілком справедливо. Однак система, над якою ви працюєте, може працювати швидше зі значеннями типу int. Визначаючи змінну як тип uint_fast*t, комп'ютер просто вибирає найбільш ефективне представлення, з яким він може працювати.

Якщо між цими уявленнями немає різниці, система вибирає те, що хоче, і використовує їх послідовно протягом усього часу.


9
Чому inttypes.h, а не stdint.h? Здається, що inttypes.h містить лише різні м'яко корисні пухирі плюс додавання stdint.h?
Лундін

@underscore_d Я знаю різницю. Але хто використовує stdio.h у професійних програмах, незалежно від сфери застосування?
Лундін

@Lundin Я поняття не маю, хто вони, чи існують вони! Я просто подумав, що може бути корисним надати посилання, що пояснює, що таке "м'яко корисний пух" ;-) Можливо, це допоможе людям зрозуміти, що ти маєш рацію, і їм це не потрібно.
підкреслюй_d

-1

Зауважте, що швидка версія може бути більшою, ніж 32 біти. У той час як швидкий int добре поміститься в регістр і вирівняється тощо: але він буде використовувати більше пам'яті. Якщо у вас є великий масив цих програм, ваша програма буде повільнішою за рахунок більшої кількості звернень до кешу пам'яті та пропускної здатності.

Я не думаю, що сучасний CPUS отримає користь від fast_int32, оскільки загалом розширення знаків від 32 до 64 біт може траплятися під час інструкції щодо завантаження, а думка про існування «рідного» цілого формату, який швидше, є старомодною.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.