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

Размер регистра процессора

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

Это означает, что необходимо определить размер регистров процессора, как правило, во время компиляции (поскольку тесты времени выполнения дороги).

В течение многих лет я использовал простой эвристический sizeof(nativeRegisters) == sizeof(size_t).

Он отлично работает для многих платформ, но он выглядит неправильно эвристическим для linux x32: в этом случае size_t только 32-битные, в то время как регистры все еще могут обрабатывать 64-битные. Это приводит к некоторым потерянным возможностям производительности (значимым для моего варианта использования).

Я бы хотел правильно определить полезный размер регистров процессора даже в такой ситуации.

Я подозреваю, что могу попытаться найти какой-то конкретный макрос компилятора для специального режима x32. Но мне было интересно, существует ли нечто более общее, чтобы охватить больше ситуаций. Например, другой целью будет OpenVMS 64-бит: там собственный размер регистра - 64 бит, но size_t - это всего 32 бита.

4b9b3361

Ответ 1

Нет надежного и портативного способа определения размера регистра с C. C даже не имеет понятия "регистры" (описание ключевого слова register не упоминает регистры CPU).

Но он определяет набор целочисленных типов, которые являются самым быстрым типом, по крайней мере, указанного размера. <stdint.h> определяет uint_fastN_t, для N = 8, 16, 32, 64.

Если вы считаете, что регистры не менее 32 бит, то uint_fast32_t, вероятно, будет иметь тот же размер, что и регистр, либо 32, либо 64 бит. Это не гарантируется. Вот что говорит стандарт:

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

со сноской:

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

Фактически, я полагаю, что использование типов [u]int_fastN_t выражает ваши намерения более четко, чем попытки сопоставления размера регистра CPU.

Если это не работает для какой-либо цели, вам нужно добавить специальный случай #if или #ifdef для выбора подходящего типа. Но uint_fast32_t (или uint_fast16_t, если вы хотите поддерживать 16-разрядные системы), вероятно, является лучшей отправной точкой, чем size_t или int.

Быстрый эксперимент показывает, что при компиляции с gcc -mx32 обе uint_fast16_t и uint_fast32_t составляют 32 бита. Они оба 64 бит при компиляции без -mx32 (в моей системе x86_64). Это означает, что, по крайней мере, для gcc типы uint_fastN_t не выполняют то, что вы хотите. Вам понадобится специальный код для x32. (Возможно, gcc должен использовать 64-битные типы для uint_fastN_t в режиме x32. Я просто разместил этот вопрос, спрашивая об этом.)

Этот вопрос спрашивает, как определить среду x32 в препроцессоре. gcc не дает прямого способа определить это, но я только что опубликовал ответ, предлагающий использовать макросы __x86_64__ и SIZE_MAX.

Ответ 2

Итак, Intel использовала инструкции по сборке и архитектуре, которые они печатали и отправляли любому разработчику, который их хотел. Я напечатал последний набор. Однако они по-прежнему предоставляют эту БЕСПЛАТНУЮ услугу бесплатно в формате pdf. вы хотите щелкнуть ссылку - Комбинированный том набора руководств для разработчиков программного обеспечения Intel® 64 и IA-32 Archives Это даст вам подробный обзор CPU, регистров, размеров, использования и полного списка ключевых слов сборки и того, как они функционируют, которые могут использоваться в каждом семействе процессоров.

Наслаждайтесь чтением