Есть ли связь между целыми числами и размерами регистров?

StackOverflow https://stackoverflow.com/questions/1078768

Вопрос

Недавно в недавнем интервью мне задали вопрос о проблеме манипулирования строками и попросили оптимизировать производительность.Мне пришлось использовать итератор для перемещения вперед и назад между символами TCHAR (с поддержкой UNICODE — по 2 байта каждый).

Не особо задумываясь о длине массива, я совершил ошибку, использовав для перебора не size_t, а int.Я понимаю, что это не соответствует требованиям и небезопасно.

int i, size = _tcslen(str);    
for(i=0; i<size; i++){
   // code here
}

Но максимальный объем памяти, который мы можем выделить, ограничен.И если существует связь между размером int и регистров, возможно, будет безопасно использовать целое число.

Например.:Без каких-либо инструментов виртуального сопоставления мы можем сопоставить только 2 байта размера регистра.Поскольку длина TCHAR составляет 2 байта, это половина этого числа.Для любой системы, в которой int имеет 32-битный формат, это не будет проблемой, даже если вы не используете беззнаковую версию int.Люди со встроенным опытом привыкли думать о int как о 16-битном, но размер памяти на таком устройстве будет ограничен.Поэтому мне интересно, существует ли архитектурное решение по тонкой настройке между целыми числами и размерами регистров.

Это было полезно?

Решение

Стандарт C++ не определяет размер int.(Там сказано, что sizeof(char) == 1, и sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

Так что нет иметь быть отношением к размеру регистра.Полностью соответствующая реализация C++ может предоставить вам 256-байтовые целые числа на вашем ПК с 32-битными регистрами.Но это было бы неэффективно.

Так что да, на практике размер int Тип данных обычно равен размеру регистров общего назначения ЦП, поскольку это, безусловно, наиболее эффективный вариант.

Если int был больше регистра, то для простых арифметических операций потребовалось бы более одной инструкции, что было бы дорого.Если бы они были меньше регистра, то загрузка и сохранение значений регистра потребовали бы от программы маскировать неиспользуемые биты, чтобы избежать перезаписи других данных.(Именно поэтому int тип данных обычно более эффективен, чем short.)

(Некоторые языки просто требуют int быть 32-битным, и в этом случае, очевидно, нет никакой связи с размером регистра --- кроме того, что 32-битный выбран, потому что это общий размер регистра)

Другие советы

Если следовать строго стандарту, нет никакой гарантии относительно того, насколько большим/маленьким является int, не говоря уже о какой-либо связи с размером регистра.Кроме того, некоторые архитектуры имеют разные размеры регистров (т.е.:не все регистры ЦП имеют одинаковый размер), и доступ к памяти не всегда осуществляется с использованием только одного регистра (как в DOS с его адресацией «Сегмент: Смещение»).Однако, несмотря на все вышесказанное, в большинстве случаев int имеет тот же размер, что и «обычные» регистры, поскольку предполагается, что это наиболее часто используемый базовый тип, и для работы с ним оптимизированы процессоры.

AFAIK, прямой связи между размером регистра и размером int нет.

Однако, поскольку вы знаете, для какой платформы компилируете приложение, вы можете определить свой собственный псевдоним типа с нужными вам размерами:

Пример

#ifdef WIN32 // Types for Win32 target
#define Int16 short
#define Int32 int
// .. etc.
#elif defined // for another target

Затем используйте объявленные псевдонимы.

Я не совсем в курсе, если я правильно понимаю, так как здесь смешаны какие-то разные проблемы (размеры памяти, распределение, размеры регистров, производительность?).

Что я могу сказать (только заголовок), что на большинстве реальных процессоров для достижения максимальной скорости вам следует использовать целые числа, соответствующие размеру регистра.Причина в том, что при использовании меньших целых чисел вам потребуется меньше памяти. но например, в архитектуре x86 необходима дополнительная команда для преобразования.Также в Intel у вас есть проблема: доступ к невыровненной (в основном по границам регистра) памяти приводит к некоторым штрафам.Конечно, с современными процессорами все еще сложнее, поскольку процессоры способны обрабатывать команды параллельно.Таким образом, вы в конечном итоге выполняете тонкую настройку некоторой архитектуры.

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

У меня нет копии стандарта, но есть моя старая копия Язык программирования Си говорит (раздел 2.2) int Относится к «целому числу, обычно отражающему естественный размер целых чисел на хост -машине». Моя копия Язык программирования C++ говорит (раздел 4.6) « int Предполагается, что тип должен быть выбран наиболее подходящим для хранения и манипулирования целыми числами на данном компьютере».

Вы не единственный человек, который говорит: «Я признаю это. технически это недостаток, но на самом деле его нельзя использовать."

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top