Повлияет ли больший двоичный файл с частями кода, которые не выполняются в то время, на использование памяти ЦП уровня 2? - PullRequest
0 голосов
/ 11 января 2011

Похоже, что процессоры работают значительно быстрее, если их L2 не заполнен. Будет ли программисту лучше кодировать что-то, что в конечном итоге будет меньше в двоичном, даже если части этого кода не выполняются все время? Скажем, части кода, которые включены только в конфигурационном файле.

1 Ответ

4 голосов
/ 03 марта 2011

Правда несколько сложнее, я постараюсь изложить это для вас.

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

  1. Устройство предварительной выборки, по одному на каждое ядро ​​(без задержки)
  2. Кэш-память L1, одна или две (объединенные или код и данные, 2 * 64K на AMD K10) для каждого ядра (латентность скажем три клика)
  3. Кэш L2, один (512 Кбайт на AMD K10) для каждого ядра (скажем, задержка) 10)
  4. Кэш-память третьего уровня, по одному (ncores * 1 МБ на AMD K10) на процессор, используемый все ядра (латентность скажем 30)
  5. ОЗУ системы, по одному на систему, используемую всеми процессорами (например, время ожидания) 100)
  6. Синхронизация (или блокировка шины), один метод на систему, используемый всеми мастерами шины устройства (задержка не менее 300 циклов до 1 мкс при использовании старой карты PCI использует все 32 доступных часов когда автобусный мастеринг с тактированием на 33 МГц - на процессоре 3 ГГц, что означает 3000 тактов)

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

Я использую синхронизацию как уровень памяти, потому что иногда вам также нужно синхронизировать память, и это стоит времени.

Язык, который вы используете, окажет большое влияние на производительность. Программа, написанная на C, C ++ или ForTran, будет меньше и будет выполняться быстрее, чем интерпретируемая программа, такая как Basic, C # и Java. C и Fortran также дадут вам лучший контроль при организации областей данных и доступа к ним программ. Некоторые функции в языках OO (C ++, C # и Java), такие как инкапсуляция и использование стандартных классов, приводят к генерированию большего кода.

Способ написания кода также оказывает большое влияние на производительность - хотя некоторые неосведомленные люди скажут, что компиляторы настолько хороши в наши дни, что нет необходимости писать хороший исходный код. Отличный код будет означать отличную производительность, а Garbage In всегда будет приводить к Garbage Out.

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

Скорее всего, в кеш будет загружена не вся ваша программа (хотя это может быть), а скорее 32- или 64-байтовые куски ("строки кэша") данных, извлеченные из 32- или 64-байтовых адресов в вашем коде. Чем больше доступа к информации в одном из этих чанков, тем дольше будет храниться строка кеша, в которой он находится. Если ядру нужен один чанк, которого нет в L1, он будет искать его вплоть до ОЗУ, если необходимо, и подвергаться штрафным часам. циклы при этом.

Таким образом, в общем случае небольшие, сжатые и встроенные последовательности кода будут выполняться быстрее, поскольку они меньше влияют на кэш (ы). Код, который делает много обращений к другим областям кода, будет иметь большее влияние на кэш, как и код с неоптимизированными переходами. Подразделения чрезвычайно вредны, но только для выполнения рассматриваемого ядра. Видимо AMD у них намного лучше чем intel (http://gmplib.org/~tege/x86-timing.pdf).

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

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

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

Чтобы иметь разумный шанс понять эти вещи, чтобы вы могли использовать их на практическом уровне, вам необходимо будет протестировать различные конструкции и рассчитать их время, предпочтительно с помощью счетчика rdtsc (много информации об этом здесь, в stackoverflow) или с помощью профилировщика.

...