5

Во-первых, это правда, правда? Я чувствую , что читает всегда будет быстрее , чем пишет, и этот парень здесь делают некоторые эксперименты , чтобы "доказать" это. Он не объясняет почему, просто упоминает "проблемы кеширования". (и его эксперименты, кажется, не беспокоятся о предварительной загрузке)

Но я не понимаю почему. Если это имеет значение, давайте предположим, что мы говорим об архитектуре Nehalem (например, i7), которая имеет кэш L1, L2 для каждого ядра, а затем общий кеш L3.

Вероятно, это потому, что я не правильно понимаю, как работает чтение и запись, поэтому я напишу свое понимание. Пожалуйста, скажите мне, если что-то не так.

If I read some memory, following steps should happen: (assume all cache misses)

    1. Check if already in L1 cache, miss
    2. Check if in L2 cache, miss
    3. Check if in L3 cache, miss
    4. Fetch from memory into (L1?) cache

Не уверен насчет последнего шага. Проникают ли данные в кеши, что означает, что в случае пропадания кеша память сначала считывается в L3/L2/L1, а затем читается оттуда? Или он может "обойти" все кэши, а затем кэширование происходит параллельно для дальнейшего использования. (чтение = доступ ко всем кэшам + выборка из оперативной памяти в кэш + чтение из кэша?)

Then write:

    1. All caches have to be checked (read) in this case too
    2. If there's a hit, write there and since Nehalem has write through caches, 
write to memory immediately and in parallel
    3. If all caches miss, write to memory directly?

Опять не уверен насчет последнего шага. Может ли запись быть сделана "в обход" всех кешей, или запись включает в себя всегда сначала чтение в кеш, изменение кешированной копии и возможность аппаратному обеспечению сквозной записи фактически выполнять запись в область памяти в ОЗУ? (запись = чтение всех кэшей + выборка из ОЗУ в кэш + запись в кэш, параллельная запись в ОЗУ ==> запись - это почти расширенный набор чтения?)

2 ответа2

4

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

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

Для более подробной информации смотрите MSalters превосходный ответ на несколько похожий вопрос.

Я не достаточно уверен в деталях того, как кэширование взаимодействует с RAM, чтобы ответить на эту часть вопроса с какой-либо авторитетностью, поэтому я оставлю это кому-то другому.

3

Случай записи: если вам нужно что-то записать в память, и у вас есть хороший контроллер памяти, игнорирующий все кэширование, все, что вам нужно сделать, это отправить транзакцию в контроллер памяти с данными, которые вы хотите записать. Из-за правил упорядочения памяти, как только транзакция покидает ядро, вы можете перейти к следующей инструкции, потому что можете предположить, что аппаратное обеспечение выполняет запись в память. Это означает, что запись практически не занимает времени.

Случай чтения: с другой стороны, чтение - это совершенно другая операция, и ей очень помогает кэширование. Если вам нужно прочитать данные, вы не сможете перейти к следующему шагу в вашей программе, пока не получите данные. Это означает, что вам нужно сначала проверить кэши, а затем память, чтобы увидеть, где находятся данные. В зависимости от того, где находятся данные, ваша задержка будет соответственно уменьшаться. В системе без потоков, без конвейерного ядра, без предварительной загрузки вы просто сжигаете циклы ядра, ожидая возвращения данных, чтобы вы могли перейти к следующему шагу. Кэш и память на несколько порядков медленнее, чем скорость ядра / пространство регистров. Вот почему чтение намного медленнее, чем запись.

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

С точки зрения оперативной памяти: даже если мы не говорим о ядре и говорим только о контроллере ОЗУ / памяти, выполнение записи в MC приведет к тому, что MC сохранит его в буфере и отправит ответ, в котором говорится, что транзакция завершена (хотя это не так). Используя буферы, нам не нужно беспокоиться о фактической скорости записи в DIMM / RAM, потому что об этом позаботится MC. Единственное исключение из этого случая - когда вы делаете большие блоки записи и выходите за пределы возможностей буфера MC. В этом случае вы должны начать беспокоиться о скорости записи в ОЗУ. И это то, на что ссылается связанная статья. Затем вы должны начать беспокоиться о физических ограничениях чтения и скорости записи, которые затрагивает ответ Дэвида. Обычно ядро все равно делает глупость; вот почему DMA был изобретен. Но это совсем другая тема.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .