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

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

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

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

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

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


person Burcu Dogan    schedule 03.07.2009    source источник
comment
Больше похоже на запись в блоге, чем на вопрос.   -  person tvanfosson    schedule 03.07.2009
comment
Извините, мне пришлось предоставить дополнительную информацию, чтобы получить ответ. Просто запрашивать размер целого числа/регистра не имеет такого же смысла.   -  person Burcu Dogan    schedule 03.07.2009
comment
burcu- Можете ли вы объяснить, почему использование int небезопасно. Вы имеете в виду, что это может привести к переполнению здесь.   -  person Vivek Sharma    schedule 03.07.2009
comment
Нет, вопрос о том, существует ли связь между целыми числами и размерами регистров, был бы совершенно ясным вопросом. Похоронив его в фоновом режиме, мне фактически пришлось прочитать это дважды, чтобы убедиться, что это действительно то, о чем вы спрашивали.   -  person jalf    schedule 03.07.2009
comment
Вивек, да, я имел в виду переполнения. Попробовал немного отредактировать, но все равно очень долго.   -  person Burcu Dogan    schedule 03.07.2009
comment
Строка когда-либо изменялась в этом коде? В противном случае вызов _tcslen() в цикле резко ухудшит производительность.   -  person sharptooth    schedule 03.07.2009
comment
Да, обычно я сохранял размер с помощью int (назначая вне цикла), мне лучше изменить код. Спасибо.   -  person Burcu Dogan    schedule 03.07.2009


Ответы (6)


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

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

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

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

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

person jalf    schedule 03.07.2009
comment
Спасибо, это отвечает на мои вопросы, связанные с производительностью, и показывает, что не так глупо использовать целое число, если выбор платформы стабилен. - person Burcu Dogan; 03.07.2009
comment
То, что int - это размер регистра, в целом верно для 16- и 32-битных платформ, но все 64-битные платформы (о которых я знаю) имеют int как 32-битное и длинное как 64-битное. (И у них 64-битные регистры). - person Martin Tilsted; 03.07.2009
comment
но эти 64-битные архитектуры, как правило, все еще имеют все 32-битные инструкции, поэтому потери производительности нет. В чистой 64-битной архитектуре тип int, скорее всего, будет 64-битным. Может быть. Однако хороший момент. - person jalf; 03.07.2009

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

person Tal Pressman    schedule 03.07.2009

Насколько я знаю, прямой связи между размером регистра и размером int нет.

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

Пример

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

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

person Cătălin Pitiș    schedule 03.07.2009

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

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

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

person Juergen    schedule 03.07.2009

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

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

person Max Lybbert    schedule 03.07.2009

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

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

person Mr Fooz    schedule 03.07.2009