Здравствуйте, дорогие читатели. Сегодня мы поговорим про оперативную память, почему в ней возникают ошибки и как этого избежать. Обязательно проанализируем работу ОЗУ с точки зрения физики и поймём, почему система "падает" при разгоне оперативки, и за что на самом деле отвечают тайминги.
Прежде чем ответить на все эти вопросы, предлагаю сперва выяснить, что вообще такое ОЗУ и как она работает.
Что такое ОЗУ?
ОЗУ - оперативное запоминающее устройство (оперативная память), в простонародии "оперативка". Предназначена для хранения данных, с которыми процессор будет производить математические операции.
Глобальная упрощённая схема взаимодействия с данными представлена на рисунке:
Из стати о процессорах Вы уже знаете, что кэш - это сверхбыстрая память, расположенная внутри процессора. Туда попадают данные из оперативной памяти, к которым наиболее часто осуществляется запрос со стороны процессора. В ОЗУ же загружаются все данные с SSD или HDD, с которыми предполагается работа процессора при выполнении программы.
Несколько упрощая, можно утверждать, что весь объём исполняемого файла будет загружен в оперативную память. Если в исполняемом файле имеются повторяющиеся строчки кода, они будут загружены в Кэш-память.
Принцип хранения данных в ОЗУ
Любая планка оперативной памяти представляет собой печатную плату, на которой распаяно некоторое количество микросхем памяти (банки).
Каждая микросхема в своей структуре имеет огромное количество ячеек памяти - конденсаторов. Если конденсатор заряжен, это соответствует логической единице. Если разряжен - логическому нулю. Доступ к конденсаторам обеспечивает транзистор - это такой полупроводниковый прибор, поговорим чуть позже.
Не станем вдаваться в подробности организации адресации этих ячеек, это не предмет сегодняшней статьи. Но всё же не вдаваться в физику процесса я не могу (дальше Вы сами поймёте, почему).
Чуть-чуть отступим в сторону и вспомним школьную физику - конденсатор, ёмкость которого измеряется в Фарадах (Ф), а также график заряда и разряда конденсатора:
Из графиков (и основ физики) мы знаем, что конденсатор не может зарядиться мгновенно, а значит, если мы будем заряжать конденсатор от источника напряжения 5 Вольт, напряжение на конденсаторе достигнет сопоставимого уровня через некоторое время T.
В схеме А конденсатор С1 (ёмкостью 100нФ - нано Фарад) зарядится до напряжения 4.5В за время ~230 мкс (микросекунд). Это связано с тем, что максимальный ток заряда ограничен сопротивлением резистора R1 1000 Ом.
В схеме Б сопротивление резистора R2 ниже в 100 раз и составляет 10 Ом, поэтому конденсатор зарядится в 100 раз быстрее - за 2,3 мкс.
В схеме В сопротивление R3=10 Ом, но и ёмкость C3 уменьшена в 100 раз, до 1нФ. Поэтому скорость заряда возрастёт и составит 23 нс (наносекунды).
Отступим ещё немножко в сторону и вспомним, что все данные в цифровых изделиях передаются в двоичном формате: с помощью логического нуля (лог.0) и логической единицы (лог.1). Но так как каждый логический уровень - это некоторая величина напряжения, есть общепринятые стандарты. Одним из самых "древних" является транзисторно-транзисторная логика ТТЛ, которая актуальна и по сей день. Для неё установлены следующие пороги срабатывания:
Теперь плавно возвращаемся к ОЗУ. Если бы она работала на уровнях ТТЛ, то чтобы в ячейку памяти (конденсатор) записать логическую единицу, нам потребовалось бы зарядить его до уровня напряжения не ниже 2,4 Вольта. А чтобы "записать" в конденсатор лог.0, достаточно его разрядить до уровня не выше 0,4 Вольта. Вроде, всё просто, не правда ли?) Давайте посмотрим, как может выглядеть блок из 4 ячеек памяти:
Внизу на схеме мы можем видеть конденсаторы С4-С7, заряженные до определённых значений напряжения. На С4, С5 и С7 у нас логические единицы, а на С6 - логический ноль (вспоминаем уровни ТТЛ). Транзисторы обеспечивают доступ к данным. Когда на затвор транзистора (адресная шина) приходит логическая единица, транзистор открывается (как кран) и напряжение конденсатора появляется на линии данных. То есть, чтобы на линии данных D1 возникло напряжение 2,9В (заряд конденсатора С5), необходимо подать лог.1 на адрес А1. Вроде, тоже не сложно. Если у Вас возникли трудности - обязательно напишите в комментариях, выпущу более детальную статью по этой теме.
Почему в ОЗУ возникают ошибки?
А вот теперь мы плавно переходим в ошибкам в памяти. Дело в том, что любой конденсатор склонен к саморазряду (за счёт наличия тока утечки) и самозаряду (определяется коэффициентом абсорбции). Не станем рассматривать эти физические процессы, просто примите эту информацию как аксиому.
Кроме того, транзисторы хоть и закрываются "намертво", не пропуская электрический ток, но у них тоже есть утечка. В результате несовершенства двух этих базовых для ОЗУ элементов, напряжение заряженного конденсатора медленно уменьшается (а разряженного может увеличиваться). И это - вполне естественный процесс! А если сюда добавить заводской брак, или просто низкое качество исполнения чипа памяти - можем получить память, выдающую ошибки. Помните эту замечательную программу MemTest?)
По суди дела, программа заряжает и разряжает ячейки памяти, проверяя сохраняемость заряда конденсатора. Ну, это я совсем грубо выразил мысль, конечно, но суть именно в этом.
По каким ещё причинам память может выдать искажённую информацию в ответ на запрос процессора? Причин несколько:
- Самозаряд/саморазряд ячейки памяти по причине низкого качества конденсатора/транзистора в ячейке;
- Влияние внешних электромагнитных полей (наводок);
- Космическое излучение;
- Повышенное сопротивление линии данных (плохой контакт в разъёме, например, препятствующий быстрому заряду ячейки).
Надеюсь, с этим разобрались. Теперь идём дальше.
Принцип передачи данных между процессором и ОЗУ
Многие из Вас могли видеть на материнской плате большое количество токоведущих дорожек, соединяющих слоты ОЗУ и процессор. Рассмотрим небольшую схему передачи сигнала:
По линии D0 (данные) передаётся цифровая последовательность логических нулей и единиц. Но так как любой логический уровень - это напряжение, значит, "должен быть второй провод!" ))))) И действительно, передача данных происходит относительно "земли" GND - Ground.
Из курса физики Вы можете помнить, что простейший конденсатор - это две токопроводящие обкладки, между которыми есть диэлектрик. А теперь давайте взглянем на материнскую плату в разрезе:
Теперь становится понятно, зачем на предыдущей схеме между линиями передачи данных и землёй я нарисовал конденсаторы - это паразитная ёмкость, которая наносит вред. Она образовывается между всеми проводниками на плате, разделённых диэлектриком. И не важно, на одном слое платы они находятся, или на разных.
Именно из-за этой самой паразитной ёмкости наш сигнал уже перестаёт быть таким красивым и "правильно цифровым":
Смотрите, если в самом начале, на "определённом уровне абстракции" мы имели чёткие нули и единицы, то реальная форма сигнала не такая уж и красивая, потому что линия имеет паразитную ёмкость, которую приходится заряжать. А раз есть ёмкость, значит, напряжение не может возникнуть мгновенно - требуется время на её зарядку.
Если же паразитная ёмкость достаточно велика, а передатчик сигнала имеет малую мощность (ток ограничен), эта самая паразитная ёмкость не будет успевать заряжаться, в результате чего сигнал не превысит порог срабатывания в 2,4В. На рисунке мы видим, что под влиянием паразитной ёмкости первая переданная логическая единица не смогла достигнуть своего уровня, равно как и вторая. За счёт того, что при передаче третьей лог.1 ёмкость уже была подзаряжена, ей-таки удалось достигнуть уровня срабатывания, но следом идущий ноль обречён на провал - ёмкость не успела разрядиться!
Как избежать возникновения ошибок в ОЗУ
Что мы можем сделать в таком случае? Вариантов не так много:
- снижать величину паразитной ёмкости;
- увеличивать мощность источника сигнала (имея большой ток, он сможет быстрее заряжать паразитную ёмкость);
- снизить логические уровни (намного быстрее зарядить конденсатор до 1В, чем до 5В);
- увеличить длительность такта, то есть, длительность передачи каждого логического состояния (0 или 1).
Производители цифровой техники не дураки, поэтому идут сразу всеми доступными способами (ну, почти). Именно поэтому DDR4 работает с уровнями 1,2В, а DDR3 работала с уровнями 1,5В. DDR5 работает с ещё более низкими уровнями - 1,1В.
Так всё же, как избежать некорректной работы ОЗУ пользователю? Тут всё достаточно просто:
- в качестве базы использовать хорошую материнскую плату, производитель которой позаботился о параметрах паразитной ёмкости и может гарантировать работу ОЗУ на больших частотах. Вполне понятно, что материнка за 4000р вряд ли сможет сравниться в этом плане с материнкой за 20к, хотя бывают и исключения. И нет, это не призыв покупать дорогущие материнские платы (об этом ещё будет отдельная статья). Просто следует внимательно изучать документацию.
- как бы то ни было странно, использовать хорошую оперативную память, от именитых производителей. Чаще всего слышу о проблемах с ОЗУ, приобретённой на АлиЭкспресс.
- использовать комфортные для ОЗУ тайминги, не препятствующие работе ячеек памяти (Вы уже вполне могли догадаться о чём речь, но далее по тексту мы ещё поговорим о таймингах).
- применять память с коррекцией ошибок (об этом мы ещё поговорим в следующей статье).
Про тайминги
И вот, наконец-то настало время кратко затронуть тему таймингов. Более подробно о них мы поговорим в следующей статье, которая будет посвящена DDR4 и DDR5, а также сравнению этих стандартов памяти (и вообще, стоит ли переходить на DDR5). Поэтому не забудьте подписаться на канал, чтобы не пропустить новую статью!)
Тайминги оперативной памяти - это задержки, которые возникают при работе ОЗУ перед фактическим выполнением команды процессора. Существуют следующие тайминги:
- CAS Latency (CL - самый "главный" тайминг) характеризует количество тактов, которое проходит между отправкой запроса со стороны процессора и последующим ответом со стороны ОЗУ;
- RAS to CAS Delay - число тактов, которое требуется для организации доступа к ячейке памяти (открытию всех транзисторов по дороге);
- RAS Precharge - число тактов, которое требуется для перехода к другому блоку данных (закрыть одну часть транзисторов, открыть другую часть);
- Row Activate Time - количество тактов, отведённое контроллеру памяти для работы со строкой.
Стало понятнее?) Не думаю) Скажу лишь, что сама оперативная память периодически перезаряжает ячейки памяти, чтобы восполнить актуальный уровень заряда, и этот процесс тоже требует время. Все переходные процессы выливаются в определённые временные задержки, что в конечном итоге сказывается на общей производительности системы.
Краткий итог
Сегодня мы разобрались в базовых вопросах, связанных с работой оперативной памяти. Изучили "физику процесса", пусть и весьма поверхностно. На мой взгляд, этой информации более, чем достаточно для перехода к следующей статье, в которой мы поговорим про DDR4 и DDR5, затронем тему буферизованной оперативной памяти, а также контроль чётности ECC.
А на этом у меня пока всё, с Вами был Народный ДОобЗОР, всем пока!)