Какова стоимость доступа к памяти? - PullRequest
8 голосов
/ 14 июня 2010

Нам нравится думать, что доступ к памяти быстрый и постоянный, но на современных архитектурах / ОС это не обязательно так.

Рассмотрим следующий код C:

int i = 34;
int *p = &i;

// do something that may or may not involve i and p

{...}

// 3 days later:

*p = 643;

Чтоявляется оценочной стоимостью этого последнего назначения в инструкциях ЦП, если

  • i находится в кэше L1,
  • i находится в кэше L2,
  • i находится в кеше L3,
  • i находится в собственно ОЗУ,
  • i выгружено на SSD-диск,
  • i выгруженона традиционный диск?

Где еще можно i быть?

Конечно, цифры не абсолютные, но меня интересуют только порядки величин.Я попытался поискать в Интернете, но на этот раз Google не благословил меня.

Ответы [ 6 ]

13 голосов
/ 14 июня 2010

Вот несколько точных цифр, демонстрирующих, что точные тайминги варьируются от семейства процессоров и версий к версии: http://www.agner.org/optimize/

Эти цифры являются хорошим ориентиром:

L1           1 ns
L2           5 ns
RAM         83 ns
Disk  13700000 ns

И как инфографика, чтобы дать вам порядки величины:

Click for the big view (источник http://news.ycombinator.com/item?id=702713)

3 голосов
/ 14 июня 2010

Norvig имеет некоторые значения с 2001 года. С тех пор все изменилось, но я думаю, что относительные скорости все еще примерно правильные.

1 голос
/ 14 июня 2010

Эти цифры постоянно меняются. Но для приблизительных оценок на 2010 год, У Кэтрин МакКинли есть отличные слайды в Интернете , которые я не считаю нужным копировать здесь.

Требуемым поисковым термином является «иерархия памяти» или «стоимость иерархии памяти».

1 голос
/ 14 июня 2010

Пока Cache / RAM / Harddisk / SSD не занят обслуживанием другого доступа (например, запросов DMA) и аппаратное обеспечение является достаточно надежным, стоимость остается постоянной (хотя они могут быть большой константой).

Когда вы получаете ошибку в кеше, и вам приходится перелистывать данные на жесткий диск, чтобы прочитать переменную, тогда это всего лишь простой запрос на чтение с жесткого диска, это огромная стоимость, так как ЦП должен: отправить прерывание ядру для чтения с жесткого диска запрос, отправьте запрос на жесткий диск, подождите, пока жесткий диск запишет данные в ОЗУ, затем прочитайте данные из ОЗУ в кэш-память и в регистр. Тем не менее, эта стоимость по-прежнему постоянна.

Фактические числа и пропорции будут варьироваться в зависимости от вашего оборудования и совместимости вашего оборудования (например, если ваш ЦП работает на 2000 МГц, а ваша ОЗУ передает данные на частоте 333 МГц, они не очень хорошо синхронизируются). Единственный способ понять это - проверить это в своей программе.

И это не преждевременная оптимизация, это микрооптимизация. Пусть компилятор беспокоится о таких деталях.

1 голос
/ 14 июня 2010

Это также может быть в регистре процессора. C / C ++ - ключевое слово «register» указывает ЦПУ сохранять переменную в регистре, но вы не можете гарантировать, что она останется или даже попадет туда.

0 голосов
/ 14 июня 2010

Где еще я могу быть?

i и *i - это разные вещи, оба они могут находиться в любом месте вашего списка. Адрес указателя может дополнительно сохраняться в регистре ЦП при выполнении назначения, поэтому его не нужно извлекать из RAM / Cache /…

Относительно производительности: сильно зависит от процессора. Думая на порядок, доступ к ОЗУ хуже, чем доступ к записям кэша, а доступ к выгруженным страницам - худший. Все они немного непредсказуемы, потому что они зависят и от других факторов (то есть от других процессоров, в зависимости от архитектуры системы).

...