2009-07-03 3 views
3

Недавно я был опрошен в недавнем интервью с проблемой манипуляции строкой и попросил оптимизировать производительность. Мне пришлось использовать итератор для перемещения между символами 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 бит, но размер памяти будет ограничен на таком устройстве. Поэтому я задаюсь вопросом, есть ли архитектурное решение тонкой настройки между целыми числами и размерами регистра.

+3

Читает больше как запись в блоге, чем вопрос. – tvanfosson

+0

К сожалению, я должен был предоставить дополнительную информацию, чтобы получить ответ. Простое задание размера integer/register не делает того же смысла. –

+0

burcu- Can u, пожалуйста, объясните, как использование int небезопасно. Вы имеете в виду, что это может привести к переполнениям здесь. –

ответ

4

В стандарте C++ не указывается размер int. (Он говорит, что sizeof(char) == 1 и sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

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

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

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

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

+1

Спасибо, это отвечает моим интересам, ориентированным на производительность, и показывает, что не так глупо использовать целое число, если выбор платформы стабилен. –

+1

То, что int - это размер регистра, вообще-то справедливо на 16 и 32-битных платформах, но все 64-битные платформы (о которых я знаю) имеют int 32bit и long as 64bit. (И у них 64-битные регистры). –

+0

, но эти 64-разрядные архитектуры, как правило, все еще имеют все 32-разрядные инструкции, поэтому нет потери производительности. В «чистой» 64-битной архитектуре int, вероятно, будет 64-разрядной. Может быть. Хороший момент. – jalf

2

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

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

Примером

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

Затем используйте декларируемые псевдонимы ,

3

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

2

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

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

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

2

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

Вы не единственный человек, который может сказать: «Я соглашусь, что this is technically a flaw, but it's not really exploitable».

2

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

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

Смежные вопросы