Почему большая память обычно медленнее, чем маленькая?
Обновлено: 21.11.2024
Вы пишете программное обеспечение, которое обрабатывает данные, и оно отлично работает, когда вы тестируете его на небольшом образце файла. Но когда вы загружаете реальные данные, ваша программа падает.
Проблема в том, что у вас недостаточно памяти: если у вас 16 ГБ ОЗУ, вы не сможете загрузить файл размером 100 ГБ. В какой-то момент у операционной системы закончится память, она не сможет ее выделить, и ваша программа перестанет работать.
Что вы можете сделать? Вы можете развернуть кластер больших данных — все, что вам нужно сделать, это:
- Получить кластер компьютеров.
- Потратьте неделю на настройку.
- Во многих случаях необходимо изучить совершенно новый API и переписать весь свой код.
Честно говоря, это немного преувеличение, поскольку вы можете развернуть кластеры больших данных в облаке, но это все равно может быть дорого и утомительно; к счастью, во многих случаях в этом нет необходимости.
Вам нужно простое и легкое решение: обработка ваших данных на одном компьютере с минимальной настройкой и максимальное использование тех же библиотек, которые вы уже используете. И в большинстве случаев вы действительно можете это сделать, используя набор методов, которые иногда называют «внешними вычислениями».
В этой статье я расскажу:
- Зачем вообще нужна оперативная память.
- Самый простой способ обработать данные, которые не помещаются в памяти, — потратить немного денег.
- Три основных программных метода обработки слишком больших объемов данных: сжатие, разбиение на фрагменты и индексирование.
Последующие статьи покажут вам, как применять эти методы к конкретным библиотекам, таким как NumPy и Pandas.
Зачем вообще нужна оперативная память?
Прежде чем мы перейдем к обсуждению решений, давайте проясним, почему проблема вообще существует. Память вашего компьютера (ОЗУ) позволяет вам читать и записывать данные, как и ваш жесткий диск — так зачем вашему компьютеру вообще нужна ОЗУ? Диск дешевле ОЗУ, поэтому он обычно может вместить все ваши данные, так почему бы вашему коду просто не ограничиться чтением и записью с диска?
Теоретически это может сработать. Однако даже более современные и быстрые твердотельные жесткие диски (SSD) намного медленнее оперативной памяти:
- Чтение с твердотельных накопителей: ~16 000 наносекунд.
- Чтение из ОЗУ: ~100 наносекунд
Если вам нужны быстрые вычисления, данные должны помещаться в ОЗУ, иначе ваш код может работать в 150 раз медленнее.
Решение 💰: больше оперативной памяти
Самое простое решение проблемы нехватки оперативной памяти — выбросить деньги на решение проблемы. Вы можете либо купить компьютер, либо арендовать виртуальную машину (ВМ) в облаке с гораздо большим объемом памяти, чем у большинства ноутбуков. В ноябре 2019 года с минимальным поиском и очень небольшим сравнением цен я обнаружил, что вы можете:
- Купите Thinkpad M720 Tower с 6 ядрами и 64 ГБ ОЗУ за 1074 доллара США.
- Арендуйте виртуальную машину в облаке с 64 ядрами и 432 ГБ ОЗУ за 3,62 доллара США в час.
Это всего лишь цифры, которые я нашел с минимальными усилиями, и, немного подробней, вы, вероятно, сможете добиться еще большего успеха.
Если, потратив немного денег на оборудование, ваши данные поместятся в ОЗУ, часто это самое дешевое решение: в конце концов, ваше время стоит довольно дорого. Однако иногда этого недостаточно.
Например, если вы выполняете много заданий по обработке данных в течение определенного периода времени, облачные вычисления могут быть естественным, но дорогостоящим решением. На одном задании стоимость вычислений для программного обеспечения, над которым я работал, израсходовала бы весь наш прогнозируемый доход от продукта, включая самый важный доход, необходимый для выплаты моей зарплаты.
Если покупка/аренда дополнительной оперативной памяти недостаточна или невозможна, следующим шагом будет выяснить, как уменьшить использование памяти, изменив программное обеспечение.
Сжатие означает использование другого представления данных, при котором используется меньше памяти. Существует две формы сжатия:
- Без потерь. Данные, которые вы сохраняете, содержат ту же информацию, что и исходные данные.
- Потери: данные, которые вы сохраняете, теряют некоторые детали исходных данных, но таким образом, что в идеале это не сильно влияет на результаты ваших вычислений.
Для ясности: я не говорю о файлах ZIP или gzip, поскольку они обычно предполагают сжатие на диске. Чтобы обработать данные из ZIP-файла, вы обычно распаковываете его как часть загрузки файлов в память. Так что это не поможет.
Что вам нужно, так это сжатие представления в памяти.
Например, предположим, что ваши данные имеют два значения и всегда будут иметь только эти два значения: "ДОСТУПНО" и "НЕДОСТУПНО" . Вместо того, чтобы хранить их в виде строки с ~ 10 или более байтами на запись, вы можете сохранить их как логическое значение, True или False , которое вы можете сохранить в 1 байте. Вы можете даже сократить представление до одного бита, необходимого для представления логического значения, что сократит использование памяти еще в 8 раз.
Разбиение на фрагменты полезно, когда вам нужно обработать все данные, но не нужно сразу загружать все данные в память. Вместо этого вы можете загружать его в память порциями, обрабатывая данные по одной порции (или, как мы обсудим в следующей статье, несколько порций параллельно).
Предположим, например, что вы хотите найти самое длинное слово в книге. Вы можете загрузить все данные в память сразу:
Но поскольку в нашем случае книга не помещается в памяти, вместо этого вы можете загружать книгу постранично:
Вы используете гораздо меньше памяти, поскольку в любой момент времени в памяти находится только одна страница книги. И в конце вы все равно получите тот же ответ.
Вы можете узнать больше о фрагментировании в Pandas и о форматах хранения NumPy, которые делают возможным фрагментирование.
Индексирование полезно, когда вам нужно использовать только подмножество данных, и вы предполагаете загружать разные подмножества данных в разное время.
Вы можете решить этот вариант использования с помощью фрагментации: загружать все данные каждый раз и просто отфильтровывать данные, которые вам не нужны. Но это медленно, так как вам нужно загрузить много нерелевантных данных.
Если вам нужна только часть данных, вместо фрагментации лучше использовать индекс, сводку данных, которая подскажет, где найти нужные данные.
Представьте, что вы хотите прочитать только те части книги, в которых говорится о трубкозубах. Если бы вы использовали фрагментацию, вы бы прочитали всю книгу, страницу за страницей, в поисках трубкозуба, но это заняло бы довольно много времени.
Или вы можете перейти в конец книги, где находится указатель книги, и найти запись для "Aardvarks". Он может предложить вам прочитать страницы 7, 19 и 120-123. Так что теперь вы можете читать эти страницы, и только эти страницы, что намного быстрее.
Это работает, потому что указатель намного меньше, чем полная книга, поэтому загрузка указателя в память для поиска соответствующих данных намного проще.
Простейший метод индексации
Самый простой и наиболее распространенный способ реализации индексации — это присвоение файлам имен в каталоге:
Если вам нужны данные за март 2019 года, просто загрузите файл 2019-Mar.csv – нет необходимости загружать данные за февраль, июль или любой другой месяц.
Вы можете узнать больше об индексировании в Pandas, а также о некоторых оптимизациях при загрузке индексированных данных из базы данных SQL.
Следующие шаги: применение этих методов
Самое простое решение проблемы нехватки оперативной памяти – потратить деньги на увеличение объема оперативной памяти. Но если в вашем случае это невозможно или недостаточно, вы так или иначе обнаружите, что используете сжатие, фрагментацию или индексирование.
Эти методы используются во многих различных программных пакетах и инструментах. Даже системы больших данных построены на этих методах: например, использование нескольких компьютеров для обработки фрагментов данных.
В последующих статьях я покажу вам, как применять эти методы с конкретными библиотеками и инструментами: NumPy, Pandas и даже ZIP-файлами. Если вы хотите читать эти статьи по мере их выхода, подпишитесь на мою рассылку в форме ниже.
Узнайте еще больше о способах сокращения использования памяти — прочтите остальную часть руководства по наборам данных, превышающим объем памяти, для Python.
Тратить время и деньги на процессы, использующие слишком много памяти?
Ваш пакетный процесс Python использует слишком много памяти, и вы понятия не имеете, какая часть вашего кода отвечает за это.
Вам нужен инструмент, который точно подскажет, на чем следует сосредоточить усилия по оптимизации, инструмент, разработанный для специалистов по обработке и анализу данных. Узнайте, чем может помочь профилировщик памяти Fil.
Как вы обрабатываете большие наборы данных с ограниченным объемом памяти?
Получите бесплатную памятку, в которой рассказывается, как обрабатывать большие объемы данных с ограниченным объемом памяти с помощью Python, NumPy и Pandas.
Кроме того, примерно каждую неделю вы будете получать новые статьи, в которых рассказывается, как обрабатывать большие данные и, в более общем плане, улучшать свои навыки разработки программного обеспечения, от тестирования до упаковки и повышения производительности:
Глава 9. Будущее стековых компьютеров
9.4 ОГРАНИЧЕНИЯ ПРОПУСКНОЙ СПОСОБНОСТИ ПАМЯТИ
Возможно, самая большая проблема, с которой сталкивались компьютерные архитекторы на протяжении многих лет, — это проблема пропускной способности памяти. Пропускная способность памяти — это количество информации, которое может быть передано в память и из памяти в единицу времени. Другими словами, пропускная способность памяти определяет, как часто значения могут быть доступны из памяти.
Суть проблемы в том, что память программ обычно намного больше с точки зрения количества транзисторов или других устройств, чем процессор. Это означает, что процессор можно легко сделать быстрее, чем память, не выходя за рамки бюджета. Это следует из общего наблюдения, что более быстрые компоненты, как правило, дороже, потребляют больше энергии и т. д. для любой данной технологии изготовления и геометрии.
9.4.1 История проблем с пропускной способностью памяти
Призрак ограничений пропускной способности памяти появлялся и исчезал на протяжении всей истории разработки компьютеров.Вначале люди были благодарны за то, что компьютеры вообще работали, поэтому скорость памяти программ и скорость процессора не были проблемой. Когда появились электронные компьютеры, большая часть памяти компьютера фактически была магнитной лентой, используемой для файлов данных, но это было лучше, чем ничего.
Память на магнитных сердечниках, использовавшаяся в ранних больших компьютерах, была очень медленной. Это породило очень сложные наборы инструкций, каждая из которых включала в себя много работы. Это также сделало практичный микрокод, поскольку небольшой объем памяти микрокода можно было сделать таким же быстрым, как процессор, без ущерба для бюджета, а большой объем памяти программ - нет. Когда полупроводниковая память стала доступной, кэш-память, в которой сохранялись небольшие фрагменты программы, особенно циклы, для повторного использования во время выполнения, стала популярной. Кэш-память становилась все больше и больше, так что все больше и больше программ размещалось в кэш-памяти, которая была достаточно быстрой, чтобы соответствовать скорости процессора.
Затем появились микропроцессоры. Первые были достаточно медленными, чтобы имеющиеся чипы программной памяти были достаточно быстрыми (и опять же, проблема заключалась не в том, насколько быстро они работали, а в том, насколько удивительно, что они вообще работали). Проблема с пропускной способностью памяти была на время устранена. Производители микропроцессоров пошли по стопам больших систем и использовали микрокод со сложными наборами инструкций.
Основные микропроцессоры развивались довольно быстро, а затем начали нуждаться в "состояниях ожидания" при доступе к памяти. Состояние ожидания — это тактовый цикл, потерянный процессором в ожидании ответа памяти, когда процессор работает быстрее, чем его микросхемы памяти. Одним из простых решений этой проблемы является покупка более быстрых микросхем памяти. Другое простое решение — просто подождать, пока производители микросхем памяти не создадут более быструю память по доступной цене. Наконец, микропроцессоры CISC представили кэш-память и другие методы, заимствованные из больших систем, в попытке перенести все больше и больше программ в быструю память.
Машины RISC расстроили всех, заявив, что процессоры с обычным микрокодом плохи. Вместо этого они используют набор инструкций очень низкого уровня, который лучше всего можно описать как сгенерированный компилятором микрокод, который находится в памяти программы. Утверждается, что этот подход дает значительные преимущества, но при допустимом увеличении требований к пропускной способности памяти. Производительность компьютеров RISC сильно зависит от кэш-памяти.
9.4.2 Текущие проблемы с пропускной способностью памяти
С последними поколениями компьютеров возникла новая проблема. Микросхемы кэш-памяти не будут достаточно быстрыми, чтобы поспевать за процессорами будущего. На самом деле это не потому, что скорость переключения транзисторов процессора увеличивается быстрее, чем скорость чипа памяти (вероятно, это не так). Проблема в том, что выводы процессора и чипа памяти начинают доминировать во временной картине.
Выводы становятся узким местом из-за того, что транзисторы становятся меньше и быстрее по мере того, как чипы становятся плотнее. К сожалению, контакты, которые можно спаять и соединять вместе, не стали намного меньше, за исключением очень экзотических технологий упаковки. Количество электронов, которые должны быть вытолкнуты штырьком и проводом, соединенным с штырьком, становится значительным по сравнению со способностью транзисторов выталкивать электроны, поэтому штырьки становятся узким местом. Это, в свою очередь, означает, что любая внешняя память на порядок медленнее встроенной памяти исключительно из-за задержек, вызванных переходом между микросхемами.
Теперь у нас может возникнуть ситуация, когда вся внешняя память слишком медленная, чтобы загружать процессор. Это создает потребность в дополнительном уровне скорости отклика памяти: встроенной кэш-памяти. К сожалению, у этого подхода есть фундаментальная проблема по сравнению с предыдущими подходами к памяти. Печатные платы могут быть сделаны довольно большими без каких-либо проблем. Выход печатной платы линейно зависит от количества микросхем, а печатные платы подлежат ремонту в случае обнаружения дефектов. К сожалению, выход чипов растет экспоненциально с ростом площади, а чипы не так легко ремонтировать.
Использование отдельных микросхем кэш-памяти и добавление дополнительных микросхем на печатную плату может обеспечить столько кэш-памяти, сколько необходимо в разумных пределах. Однако, если в однокристальной системе недостаточно встроенной кэш-памяти, увеличение размера микросхемы для обеспечения большего объема памяти может сделать процессор непригодным для производства из-за проблем с выходом. Огромные объемы памяти, необходимые высокоскоростным процессорам, особенно RISC-машинам, по-видимому, указывают на то, что лучшее, на что мы можем надеяться, — это скромный объем высокоскоростной кэш-памяти на кристалле и большой объем низкоскоростной внесистемной памяти. чип кэш-памяти. Теперь производительность нашей программы зависит от соотношения попаданий для двух разных кэшей. Это лучшее, на что мы можем надеяться?
9.4.3 Решение для стековой машины
Машины стека предлагают совершенно другой способ решения проблемы. Обычные машины с их кешем пытаются захватить фрагменты программ по мере их запуска. Это часть попытки повторно использовать уже извлеченные инструкции, поскольку они выполняются в циклах или очень часто вызываемых процедурах. Часть проблемы, влияющей на производительность кэша, заключается в том, что обычные языки программирования и компиляторы создают бессвязный, растянутый код. С другой стороны, стековые машины поощряют написание компактного кода с повторным использованием процедур.
Следствие того, как ведут себя программы стековых машин, заключается в том, что стековые машины не должны использовать динамически выделяемую кэш-память. Вместо этого они должны использовать небольшую, статически выделенную или управляемую операционной системой программную память для высокоскоростного выполнения выбранных подпрограмм. В эти части программной памяти могут быть помещены часто используемые подпрограммы, которые компилятор и пользователь могут использовать более свободно, зная, что они будут выполняться быстро. Поскольку машинный код стека очень компактен, значительная часть программы может находиться в высокоскоростной встроенной памяти. Это может еще больше стимулировать использование модульных, повторно используемых процедур с осознанием того, что они действительно улучшат производительность, а не ухудшат ее, как это часто бывает на других машинах. Конечно, поскольку встроенная память программ не нуждается в сложных и громоздких схемах управления для управления кэшем, тем больше места доступно для дополнительной памяти программ. В процессорах с 16-разрядным стеком вполне разумно, чтобы вся программа управления в реальном времени и память данных для ее локальных переменных находились полностью на кристалле. С техпроцессом на субмикронном уровне то же самое начнет происходить и с 32-разрядными процессорами стека.
Чтобы понять, как может работать этот другой подход к иерархии памяти, рассмотрим машину с микрокодом, такую как RTX 32P. Большие динамические ОЗУ могут использоваться для хранения большей части программы и ее данных. На самом деле, это действительно крайний случай, потому что программам для RTX 32P редко требуется больше, чем емкость его микросхем статической памяти для программ, но предположим, что это так или иначе. Динамическая RAMS образует элемент хранения для самых высоких уровней программы, которые выполняются нечасто, а также для данных, доступ к которым осуществляется редко или нечасто.
Далее в систему добавляются микросхемы статической памяти. Они используются для слоев программы среднего уровня, которые выполняются довольно часто. Кроме того, программные данные, которыми будут часто манипулировать, могут находиться в этой памяти или могут быть скопированы из динамической памяти на период времени, когда они потребуются. На практике может быть два уровня микросхем статической памяти: большие медленные и маленькие быстрые, каждый с разной мощностью, стоимостью и характеристиками места на печатной плате.
Следующим в иерархии может быть встроенная память программ. Внутренние циклы важных процедур программы могут находиться здесь для быстрого доступа к ним процессора. Несколько сотен байт ОЗУ для программ могут легко поместиться на чипе процессора для данных и программы. В случае микросхем, которые запускают специальные программы (что часто имеет место в среде встроенных систем реального времени), несколько тысяч байт ПЗУ программ могут находиться на кристалле. На практике любой язык может использовать множество общих подпрограмм в ПЗУ для помощи программисту и компилятору.
Наконец, память микрокода находится на кристалле для фактического управления процессором. В смысле иерархии памяти память микрокода можно рассматривать как еще один уровень памяти программ. Он содержит наиболее часто выполняемые действия для процессора, соответствующие поддерживаемым машинным инструкциям. Опять же, смесь ПЗУ и ОЗУ уместна. И, конечно же, стек данных действует как устройство быстрого доступа для хранения промежуточных результатов вычислений.
Тогда у нас есть многоуровневая иерархия размеров и скоростей памяти по всей системе. Идея иерархии не нова. Новым является мысль о том, что во время выполнения им не нужно управлять аппаратным обеспечением. Компилятор и программист могут легко с этим справиться. Суть в том, что, поскольку стековые программы очень малы, значительный объем кода может находиться на каждом уровне иерархии со статическим распределением. Поскольку стековые машины поддерживают очень быстрые вызовы процедур, в высокоскоростной памяти должны храниться только внутренние циклы или небольшие сегменты кода, которые часто выполняются, а не весь объем определяемых пользователем процедур. Это означает, что динамическое выделение памяти действительно не требуется.
Кэш-память играет ключевую роль в компьютерах. Фактически, все современные компьютерные системы, включая настольные ПК, серверы в корпоративных центрах обработки данных и облачные вычислительные ресурсы, имеют небольшие объемы очень быстрой статической оперативной памяти (SRAM), расположенной очень близко к центральному процессору (ЦП). Эта память называется кэш-памятью.
Несмотря на свой небольшой размер по сравнению с основной памятью (ОЗУ) или дополнительной памятью (ресурсами хранения), кэш-память оказывает огромное влияние на общую производительность системы.
Что такое кэш-память?
Компьютерные системы оснащены жесткими дисками или твердотельными накопителями (SSD) для обеспечения большой емкости и долговременного хранения данных, а также оперативной памятью, которая используется для хранения данных и программного кода, которые центральный процессор использует или собирается использовать. понадобится в самое ближайшее время. Оперативная память намного быстрее, чем жесткий диск или хранилище SSD. Обычно он состоит из динамической памяти с произвольным доступом (DRAM), которая также дороже в пересчете на гигабайт или сохраненные данные.
Но ЦП работает намного быстрее, чем ОЗУ, поэтому иногда ему приходится ждать, пока инструкции или данные считываются из ОЗУ, прежде чем он сможет продолжить обработку, что снижает общую производительность компьютерной системы.
Чтобы этого не происходило, компьютерные системы обычно оснащаются кэш-памятью: небольшим объемом динамической памяти с произвольным доступом (DRAM), которая является очень быстрой, но очень дорогой и расположена очень близко к самому ЦП.
В этой кэш-памяти хранятся данные или инструкции, которые процессор может использовать в ближайшем будущем. Поскольку это избавляет ЦП от ожидания, для повышения производительности чтения используется кэширование.
Кэш-память и производительность
Кэш-память повышает производительность компьютера. Кэш-память расположена очень близко к ЦП, либо на самом чипе ЦП, либо на материнской плате в непосредственной близости от ЦП и соединена специальной шиной данных. Таким образом, инструкции и данные могут быть прочитаны из него (и записаны в него) гораздо быстрее, чем в случае с обычной оперативной памятью.
Это означает, что процессор с меньшей вероятностью будет вынужден ждать — или время ожидания будет значительно сокращено. В результате очень небольшой объем кэш-памяти может привести к значительному увеличению производительности компьютера.
Как работает кэш-память?
Кэш-память работает, беря данные или инструкции по определенным адресам памяти в ОЗУ и копируя их в кэш-память вместе с записью исходного адреса этих инструкций или данных.
В результате получается таблица, содержащая небольшое количество адресов оперативной памяти и копии инструкций или данных, содержащихся в этих адресах оперативной памяти.
Кэш памяти «сработал»
Когда процессору требуются инструкции или данные из заданного адреса ОЗУ, то, прежде чем извлекать их из ОЗУ, он проверяет, содержит ли кэш-память ссылку на этот адрес ОЗУ. Если это так, то он считывает соответствующие данные или инструкции из кэш-памяти, а не из ОЗУ. Это известно как «попадание в кэш». Так как кэш-память быстрее, чем ОЗУ, и поскольку она расположена ближе к центральному процессору, она может получить и начать обработку инструкций и данных намного быстрее.
Та же процедура выполняется, когда данные или инструкции необходимо записать обратно в память. Однако в этом случае есть дополнительный шаг, потому что если что-то записывается в кэш-память, то в конечном итоге это также должно быть записано в ОЗУ.
Как это делается, зависит от политики записи кеша. Простейшая политика называется сквозной записью: при этой политике все, что записывается в кеш памяти, сразу же записывается в ОЗУ.
Альтернативная политика — «обратная запись». Используя политику «обратной записи», данные, записываемые в кэш-память, теперь сразу же записываются и в ОЗУ. Все, что записывается в кэш-память, помечается как «грязное», что означает, что оно отличается от исходных данных или инструкций, которые были считаны из ОЗУ. Когда она удаляется из кэш-памяти, то и только тогда она записывается в оперативную память, заменяя исходную информацию.
Промежуточные политики позволяют ставить «грязную» информацию в очередь и записывать обратно в ОЗУ в пакетном режиме, что может быть более эффективным, чем многократная запись по отдельности.
Кэш памяти «промах»
Если данные или инструкции по заданному адресу оперативной памяти не найдены в кэш-памяти, это называется «промахом кэша». В этом случае ЦП вынужден ждать, пока информация извлекается из ОЗУ.
На самом деле данные или инструкции извлекаются из ОЗУ и записываются в кэш-память, а затем отправляются в ЦП. Причина этого в том, что данные или инструкции, которые недавно использовались, скорее всего, снова потребуются в ближайшем будущем. Таким образом, все, что ЦП запрашивает из ОЗУ, всегда копируется в кэш-память.
(Есть исключение. Некоторые данные редко используются повторно, их можно пометить как некэшируемые. Это предотвращает ненужное занятие ценного пространства кэш-памяти данными.)
В связи с этим возникает вопрос, что произойдет, если кэш-память уже заполнена. Ответ заключается в том, что часть содержимого кэш-памяти необходимо «выселить», чтобы освободить место для новой информации, которую необходимо туда записать.
Если необходимо принять решение, кэш памяти применит «политику замены», чтобы решить, какая информация будет вытеснена.
Существует несколько возможных политик замены. Одной из наиболее распространенных является политика наименее использовавшихся (LRU). В этой политике используется принцип, согласно которому, если данные или инструкции не использовались в последнее время, то они с меньшей вероятностью потребуются в ближайшем будущем, чем данные или инструкции, которые потребовались совсем недавно.
Ключевое значение кэш-памяти
Кэш-память необходима для устранения узких мест производительности между ОЗУ и ЦП. Его использование аналогично использованию оперативной памяти в качестве дискового кеша. В этом случае часто используемые данные, хранящиеся во вторичных системах хранения (таких как жесткие диски или твердотельные накопители), временно помещаются в оперативную память, где ЦП может получить к ним доступ гораздо быстрее.
Поскольку ОЗУ дороже (но быстрее), чем вторичное хранилище, дисковые кэши меньше, чем жесткие диски или твердотельные накопители. Поскольку SRAM дороже (но быстрее), чем DRAM, кэши памяти меньше, чем RAM.
Типы кэш-памяти
- Первичный кэш Большая часть кэш-памяти физически расположена на том же кристалле, что и сам ЦП, а часть, ближайшая к ядрам ЦП, иногда называется первичным кэшем, хотя этот термин больше не используется.
- Вторичная кэш-память Часто это относится к дополнительной части кэш-памяти, расположенной на отдельной микросхеме материнской платы рядом с процессором. Этот термин также больше не используется, поскольку большая часть кэш-памяти теперь расположена на самом кристалле ЦП.
Уровни кэш-памяти
Современные компьютерные системы имеют более одной части кэш-памяти, и эти кэши различаются по размеру и близости к ядрам процессора, а значит, и по скорости. Они известны как уровни кэша.
Самая маленькая и самая быстрая кэш-память — это кэш-память 1-го уровня, или кэш-память L1, а следующей является кэш-память L2. Большинство систем теперь имеют кэш-память L3, а с момента появления чипов Skylake Intel также добавила кэш-память L4 в некоторые из своих процессоров.
Уровень 1
Кэш L1 — это кэш-память, встроенная в сам ЦП. Он работает на той же тактовой частоте, что и процессор. Это самый дорогой тип кэш-памяти, поэтому его размер крайне ограничен. Но поскольку он очень быстрый, это первое место, где процессор будет искать данные или инструкции, которые могли быть буферизованы из ОЗУ.
На самом деле в большинстве современных процессоров кэш L1 разделен на две части: раздел данных (L1d) и раздел инструкций (L1i). Они содержат данные и инструкции соответственно.
Современный ЦП может иметь размер кэша порядка 32 КБ L1i и L1d на ядро.
Уровень 2
Кэш L2 также может располагаться в микросхеме ЦП, хотя и не так близко к ядру, как кэш L1. Или, что реже, он может быть расположен на отдельном чипе рядом с процессором. Кэш L2 дешевле и больше, чем кэш L1, поэтому размер кэша L2, как правило, больше и может составлять порядка 256 КБ на ядро.
Уровень 3
Кэш уровня 3, как правило, намного больше, чем кэш L1 или L2, но он также отличается еще одним важным аспектом. В то время как кэши L1 и L2 являются частными для каждого ядра процессора, кэш L3, как правило, является общим кешем, общим для всех ядер. Это позволяет ему играть важную роль в обмене данными и межъядерной связи. Кэш L3 может иметь размер порядка 2 МБ на ядро.
Отображение кэша
Кэш-память, как уже говорилось, чрезвычайно быстра, то есть ее можно очень быстро считывать.
Но существует потенциальное узкое место: прежде чем данные можно будет считать из кэш-памяти, их необходимо найти. Процессор знает адрес оперативной памяти данных или инструкции, которую он хочет прочитать. Он должен выполнить поиск в кеше памяти, чтобы увидеть, есть ли ссылка на этот адрес ОЗУ в кеше памяти вместе со связанными данными или инструкциями.
Существует несколько способов отображения данных или инструкций из ОЗУ в кэш памяти, и они напрямую влияют на скорость их поиска. Но есть компромисс: минимизация времени поиска также сводит к минимуму вероятность попадания в кеш, а максимизация вероятности попадания в кеш увеличивает вероятное время поиска.
Обычно используются следующие методы сопоставления кеша:
Прямое сопоставление
При использовании кеша с прямым отображением существует только одно место в кэш-памяти, в котором может храниться данный блок данных из ОЗУ.
Это означает, что ЦП должен заглянуть только в одно место в кэше памяти, чтобы увидеть, присутствуют ли данные или инструкции, которые он ищет, и если это так, они будут найдены очень быстро. Недостаток кэша с прямым отображением заключается в том, что он сильно ограничивает объем данных или инструкций, которые можно хранить в кэше памяти, поэтому попадания в кэш случаются редко.
Ассоциативное сопоставление
Также известное как полностью связанное сопоставление, оно противоположно прямому сопоставлению. При ассоциативной схеме отображения любой блок данных или инструкций из ОЗУ можно поместить в любой блок кэш-памяти. Это означает, что ЦП должен просмотреть всю кэш-память, чтобы увидеть, содержит ли она то, что он ищет, но вероятность попадания в кеш гораздо выше.
Набор-ассоциативное сопоставление
Компромиссом между двумя типами сопоставления является установленное ассоциативное сопоставление, которое позволяет сопоставлять блок оперативной памяти с ограниченным числом различных блоков кэша памяти.
Поиск в двухсторонней системе занимает в два раза больше времени, чем в системе с прямым сопоставлением, поскольку ЦП должен искать в двух местах, а не только в одном, но вероятность попадания в кэш гораздо выше.
Воспоминания содержат один или несколько битов информации:
Содержимое памяти остается неизменным до тех пор, пока не будет перезаписано новым битовым шаблоном. Для некоторых воспоминаний содержимое «теряется» при отключении питания памяти.
Компьютеры используют множество различных типов памяти (полупроводниковая память, магнитные диски и ленты, компакт-диски и т. д.) для хранения данных и программ. Каждый тип памяти имеет свои особенности и области применения.
Зарегистрировать память
Регистры — это память, расположенная в центральном процессоре (ЦП). Их мало (редко бывает больше 64 регистров), а также небольшой размер, обычно регистр имеет размер менее 64 бит.
Однако содержимое регистра можно «прочитать» или «записать» очень быстро, часто на порядок быстрее, чем в основной памяти, и на несколько порядков быстрее, чем в дисковой памяти.
Различные типы регистров встречаются в ЦП. Регистры общего назначения доступны для общего использования программистом. Если из контекста не следует иное, мы будем использовать термин «Регистр» для обозначения регистра общего назначения внутри ЦП. Большинство современных процессоров имеют от 16 до 64 регистров общего назначения. Регистры специального назначения имеют особое назначение и либо не программируются, либо являются внутренними для ЦП, либо доступ к ним осуществляется программистом с помощью специальных инструкций.
Примеры таких регистров включают:
Хотя размер регистра (размер битовой группы регистров) имеет тенденцию варьироваться в зависимости от типа регистра, размер слова архитектуры часто (но не всегда!) определяется размером регистров общего назначения. р>
В отличие от основной памяти и дисковой памяти, регистры «адресуются» напрямую с помощью специальных инструкций или путем кодирования номера регистра в компьютерной инструкции. На уровне языка программирования (ассемблера) ЦП регистры обычно обозначаются специальными идентификаторами (например, R0, R1, R7, SP, PC)
И последнее: содержимое регистра теряется при отключении питания ЦП, поэтому регистры не подходят для хранения долговременной информации или информации, необходимой для хранения после отключения питания или сбоя. Однако регистры являются самой быстрой памятью, и их использование может привести к тому, что программы будут выполняться очень быстро.
Основная память (ОЗУ)
Если бы мы суммировали все биты всех регистров ЦП, общий объем памяти, вероятно, не превышал бы 5000 бит. Большинство вычислительных задач, выполняемых компьютером, требуют гораздо больше памяти. Основная память — это следующая по скорости память в компьютере, и она намного больше по размеру.
Персональный компьютер | 256 МБ | Файловый сервер | 4 ГБ |
Мейнфрейм базы данных | 32 ГБ тд> |