Контакты

Что такое кэш процессора. Влияние кэш-памяти на производительность компьютера Кэш память в современных процессорах

Кэш процессора - специальная память внутри процессора для ускорения обращения к оперативной памяти. Иногда кэш процессора называют сверхоперативной памятью, потому что доступ к ней происходит за очень маленькое время. Обычно кэш в процессорах делают на основе классических триггеров - так называемой статической памяти (SRAM). Для примера, оперативная память построена на основе конденсаторов, которые время от времени подзаряжаются. Тригеры обеспечивают практически мгновенный доступ к себе, но у них есть два главных недостатка:

  • относительно высокая стоимость изготовления
  • постоянное потребление энергии
  • Именно эти ограничения SRAM не позволяют делать на основе нее оперативную память.

    Уровни кэша процессора

    В современных процессорах кэш делится на несколько уровней

    Алгоритм работы кэш памяти

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

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

    Когда процессор делает запрос на запись в оперативную память, то контроллер кэша обновляет значение у себя и передает его дальше - на более низкие уровни. В конце концов значение оказывается в оперативной памяти. По такому алгоритму обычно работает кэш на запись. Можно конечно сохранять значение только к кэше, но тогда остальные компоненты (например, DMA - прямой доступ к памяти) при доступе к оперативной памяти рискуют получить устаревшее значение.

    Частота работы кэш-памяти

    Поскольку SRAM память модут работать на очень болших частотах, кэш-память процессора обычно работает на той же частоте, что и сам процессор. Это дополнительно увеличивает скорость работы с этим видом памяти.

    Интеллектуальная кэш-память

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

    Первый кэш

    Некоторое подобие кэша было еще в процессоре 8086. В нем было 6 байт кэша команд. Небольшое количество, без больших интеллектуальных способностей, но он значительно повышал быстродействие системы. Но настоящий кэш стал использоваться с процессором 80386. В те времена для обращения к оперативной памяти нужно было 120 нс времени. Но рядом с процессором ставили специальную микросхему кэш-памяти и доступ к ней просходил в 12 раз быстрее, чем к оперативной памяти. Но эта память (SRAM) была достаточно дорогой и ставить микросхему кэш памяти большого объема было нерентабельно. Поэтому первые кэши процессора были ограничены объемом 64 килобайт и устанавливались они отдельно. Начиная с процесора 80486 кэш процессора стал оправдывать свое название, потому что устанавливался прямо в процессоре.

    Место установки кэша

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

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

    Кэш центрального процессора

    Функционирование

    Диаграмма кэша памяти ЦПУ

    Кэш - это память с большей скоростью доступа, предназначенная для ускорения обращения к данным, содержащимся постоянно в памяти с меньшей скоростью доступа (далее «основная память»). Кэширование применяется ЦПУ , жёсткими дисками , браузерами и веб-серверами .

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

    Когда клиент кэша (ЦПУ, веб-браузер, операционная система) обращается к данным, прежде всего исследуется кэш. Если в кэше найдена запись с идентификатором, совпадающим с идентификатором затребованного элемента данных, то используются элементы данных в кэше. Такой случай называется попаданием кэша . Если в кэше не найдено записей, содержащих затребованный элемент данных, то он читается из основной памяти в кэш, и становятся доступным для последующих обращений. Такой случай называется промахом кэша . Процент обращений к кэшу, когда в нём найден результат, называется уровнем попаданий или коэффициентом попаданий в кэш.

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

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

    При модификации элементов данных в кэше выполняется их обновление в основной памяти. Задержка во времени между модификацией данных в кэше и обновлением основной памяти управляется так называемой политикой записи .

    В кэше с немедленной записью каждое изменение вызывает синхронное обновление данных в основной памяти.

    В кэше с отложенной записью (или обратной записью ) обновление происходит в случае вытеснения элемента данных, периодически или по запросу клиента. Для отслеживания модифицированных элементов данных записи кэша хранят признак модификации (изменённый или «грязный» ). Промах в кэше с отложенной записью может потребовать два обращения к основной памяти: первое для записи заменяемых данных из кэша, второе для чтения необходимого элемента данных.

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

    Почти все разработчики знают, что кэш процессора - это такая маленькая, но быстрая память, в которой хранятся данные из недавно посещённых областей памяти - определение краткое и довольно точное. Тем не менее, знание «скучных» подробностей относительно механизмов работы кэша необходимо для понимания факторов влияющих на производительность кода.

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

    Habracut - - -

    Пример 1: доступ к памяти и производительность

    Как вы думаете, насколько второй цикл быстрее первого?
    int arr = new int ;

    // первый
    for (int i = 0; i < arr.Length; i++) arr[i] *= 3;

    // второй
    for (int i = 0; i < arr.Length; i += 16) arr[i] *= 3;


    Первый цикл умножает все значения массива на 3, второй цикл только каждое шестнадцатое значение. Второй цикл совершает только 6% работы первого цикла, но на современных машинах оба цикла выполняются примерно за равное время: 80 мс и 78 мс соответственно (на моей машине).

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

    Пример 2: влияние строк кэша

    Копнём глубже - попробуем другие значения шага, не только 1 и 16:
    for (int i = 0; i < arr.Length; i += K /* шаг */ ) arr[i] *= 3;

    Вот время работы этого цикла для различных значений шага K:

    Обратите внимание, при значениях шага от 1 до 16 время работы практически не изменяется. Но при значениях больше 16, время работы уменьшается примерно вдвое каждый раз когда мы увеличиваем шаг в два раза. Это не означает, что цикл каким-то магическим образом начинает работать быстрее, просто количество итераций при этом так же уменьшается. Ключевой момент - одинаковое время работы при значениях шага от 1 до 16.

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

    Из-за того, что 16 значений типа int занимают 64 байта, циклы с шагами от 1 до 16 обращаются к одинаковому количеству строк кэша, точнее говоря, ко всем строкам кэша массива. При шаге 32, обращение происходит к каждой второй строке, при шаге 64, к каждой четвёртой.

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

    Пример 3: размеры кэшей первого и второго уровня (L1 и L2)

    Современные процессоры, как правило, имеют два или три уровня кэшей, обычно их называют L1, L2 и L3. Для того, чтобы узнать размеры кэшей различных уровней, можно воспользоваться утилитой CoreInfo или функцией Windows API GetLogicalProcessorInfo . Оба способа так же предоставляют информацию о размере строки кэша для каждого уровня.

    На моей машине CoreInfo сообщает о кэшах данных L1 объёмом по 32 Кбайт, кэшах инструкций L1 объёмом по 32 Кбайт и кэшах данных L2 объёмом по 4 Мбайт. Каждое ядро имеет свои персональные кэши L1, кэши L2 общие для каждой пары ядер:

    Logical Processor to Cache Map: *--- Data Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 *--- Instruction Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64 -*-- Data Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 -*-- Instruction Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64 **-- Unified Cache 0, Level 2, 4 MB, Assoc 16, LineSize 64 --*- Data Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64 --*- Instruction Cache 2, Level 1, 32 KB, Assoc 8, LineSize 64 ---* Data Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64 ---* Instruction Cache 3, Level 1, 32 KB, Assoc 8, LineSize 64 --** Unified Cache 1, Level 2, 4 MB, Assoc 16, LineSize 64
    Проверим эту информацию экспериментально. Для этого, пройдёмся по нашему массиву инкрементируя каждое 16-ое значение - простой способ изменить данные в каждой строке кэша. При достижении конца, возвращаемся к началу. Проверим различные размеры массива, мы должны увидеть падение производительности когда массив перестаёт помещаться в кэши разных уровней.

    Код такой:

    int steps = 64 * 1024 * 1024; // количество итераций
    int lengthMod = arr.Length - 1; // размер массива -- степень двойки

    for (int i = 0; i < steps; i++)
    {
    // x & lengthMod = x % arr.Length, ибо степени двойки
    arr[(i * 16) & lengthMod]++;
    }


    Результаты тестов:

    На моей машине заметны падения производительности после 32 Кбайт и 4 Мбайт - это и есть размеры кэшей L1 и L2.

    Пример 4: параллелизм инструкций

    Теперь давайте взглянем на кое-что другое. По вашему мнению, какой из этих двух циклов выполнится быстрее?
    int steps = 256 * 1024 * 1024;
    int a = new int ;

    // первый
    for (int i = 0; i < steps; i++) { a++; a++; }

    // второй
    for (int i = 0; i < steps; i++) { a++; a++; }


    Оказывается, второй цикл выполняется почти в два раза быстрее, по крайней мере, на всех протестированных мной машинах. Почему? Потому, что команды внутри циклов имеют разные зависимости по данным. Команды первого имеют следующую цепочку зависимостей:

    Во втором цикле зависимости такие:

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

    Пример 5: ассоциативность кэша

    Один из ключевых вопросов, на который необходимо дать ответ при проектировании кэша - могут ли данные из определённой области памяти храниться в любых ячейках кэша или только в некоторых из них. Три возможных решения:
    1. Кэш прямого отображения , данные каждой строки кэша в оперативной памяти хранятся только в одной заранее определённой ячейке кэша. Простейший способ вычисления отображения: индекс_строки_в_памяти % количество_ячеек_кэша. Две строки, отображённые на одну и ту же ячейку, не могут находится в кэше одновременно.
    2. N-входовый частично-ассоциативный кэш , каждая строка может храниться в N различных ячейках кэша. Например, в 16-входовом кэше строка может храниться в одной из 16-ти ячеек составляющих группу. Обычно, строки с равными младшими битами индексов разделяют одну группу.
    3. Полностью ассоциативный кэш , любая строка может быть сохранена в любую ячейку кэша. Решение эквивалентно хеш-таблице по своему поведению.
    Кэши прямого отображения подвержены конфликтам, например, когда две строки соревнуются за одну ячейку, поочерёдно вытесняя друг-друга из кэша, эффективность очень низка. С другой стороны, полностью ассоциативные кэши, хотя и лишены этого недостатка, очень сложны и дороги в реализации. Частично-ассоциативные кэши - типичный компромисс между сложностью реализации и эффективностью.

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

    Так как кэш L2 имеет 65 536 ячеек (4 * 2 20 / 64) и каждая группа состоит из 16 ячеек, всего мы имеем 4 096 групп. Таким образом, младшие 12 битов индекса строки определяют к какой группе относится эта строка (2 12 = 4 096). В результате, строки с адресами кратными 262 144 (4 096 * 64) разделяют одну и ту же группу из 16-ти ячеек и соревнуются за место в ней.

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

    public static long UpdateEveryKthByte(byte arr, int K)
    {
    const int rep = 1024 * 1024; // количество итераций

    Stopwatch sw = Stopwatch.StartNew();

    int p = 0;
    for (int i = 0; i < rep; i++)
    {
    arr[p]++;

    P += K; if (p >= arr.Length) p = 0;
    }

    Sw.Stop();
    return sw.ElapsedMilliseconds;
    }


    Метод инкрементирует каждый K-ый элемент массива. По достижении конца, начинаем заново. После довольно большого количества итераций (2 20), останавливаемся. Я сделал прогоны для различных размеров массива и значений шага K. Результаты (синий - большое время работы, белый - маленькое):

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

    Разберёмся с синими областями:

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

      Некоторые из плохих значений шага - степени двойки: 256 и 512. Для примера рассмотрим шаг 512 и массив в 8 Мбайт. При этом шаге, в массиве имеются 32 участка (8 * 2 20 / 262 144), которые ведут борьбу друг с другом за ячейки в 512-ти группах кэша (262 144 / 512). Участка 32, а ячеек в кэше под каждую группу только 16, поэтому места на всех не хватает.

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

    2. Почему вертикальные линии обрываются на границе в 4 Мбайт? При размере массива в 4 Мбайт или меньше, 16-входовый кэш ведёт себя так же как и полностью ассоциативный, то есть может вместить все данные массива без конфликтов. Имеется не более 16-ти областей ведущих борьбу за одну группу кэша (262 144 * 16 = 4 * 2 20 = 4 Мбайт).
    3. Почему слева вверху находится большой синий треугольник? Потому, что при маленьком шаге и большом массиве кэш не в состоянии уместить все необходимые данные. Степень ассоциативности кэша играет тут второстепенную роль, ограничение связано с размером кэша L2.

      Например, при размере массива в 16 Мбайт и шаге 128, мы обращаемся к каждому 128-му байту, таким образом, модифицируя каждую вторую строку кэша массива. Чтобы сохранить каждую вторую строку в кэше, необходим его объём в 8 Мбайт, но на моей машине есть только 4 Мбайт.

      Даже если бы кэш был полностью ассоциативным, это не позволило бы сохранить в нём 8 Мбайт данных. Заметьте, что в уже рассмотренном примере с шагом 512 и размером массива 8 Мбайт, нам необходим только 1 Мбайт кэша, чтобы сохранить все нужные данные, но это невозможно сделать из-за недостаточной ассоциативности кэша.

    4. Почему левая сторона треугольника постепенно набирает свою интенсивность? Максимум интенсивности приходится на значение шага в 64 байта, что равно размеру строки кэша. Как мы увидели в первом и во втором примере, последовательный доступ к одной и той же строке практически ничего не стоит. Скажем, при шаге в 16 байт, мы имеем четыре обращения к памяти по цене одного.

      Так как количество итераций равно в нашем тесте при любом значении шага, то более дешёвый шаг в результате даёт меньшее время работы.

    Обнаруженные эффекты сохраняются и при больших значениях параметров:

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

    Пример 6: ложное разделение кэша

    На многоядерных машинах можно столкнуться с другой проблемой - согласование кэшей. Ядра процессора имеют частично или полностью раздельные кэши. На моей машине кэши L1 раздельны (как и обычно), так же имеются два кэша L2, общие для каждой пары ядер. Детали могут различаться, но в целом современные многоядерные процессоры имеют многоуровневые иерархические кэши. Причём самые быстрые, но и самые маленькие кэши, принадлежат индивидуальным ядрам.

    Когда одно из ядер модифицирует значение в своём кэше, другие ядра больше не могут использовать старое значение. Значение в кэшах других ядер должно быть обновлено. Более того, должна быть обновлена полностью вся строка кэша , так как кэши оперируют данными на уровне строк.

    Продемонстрируем эту проблему на следующем коде:

    private static int s_counter = new int ;

    private void UpdateCounter(int position)
    {
    for (int j = 0; j < 100000000; j++)
    {
    s_counter = s_counter + 3;
    }
    }


    Если на своей четырёхядерной машине я вызову этот метод с параметрами 0, 1, 2, 3 одновременно из четырёх потоков, то время работы составит 4.3 секунды . Но если я вызову метод с параметрами 16, 32, 48, 64, то время работы составит только 0.28 секунды .

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

    Пример 7: сложность железа

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

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

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

    Вот другой пример странных причуд железа:

    private static int A, B, C, D, E, F, G;

    private static void Weirdness()
    {
    for (int i = 0; i < 200000000; i++)
    {
    <какой-то код>
    }
    }


    Если вместо <какой-то код> подставить три разных варианта, можно получить следующие результаты:

    Инкрементирование полей A, B, C, D занимает больше времени, чем инкрементирование полей A, C, E, G. Что ещё страннее, инкрементирование полей A и C занимает больше времени, чем полей A, C и E, G. Не знаю точно каковы причины этого, но возможно они связаны с банками памяти (да-да, с обычными трёхлитровыми сберегательными банками памяти, а не то, что вы подумали ). Имеющих соображения на этот счёт, прошу высказываться в комментариях.

    У меня на машине вышеописанного не наблюдается, тем не менее, иногда бывают аномально плохие результаты - скорее всего, планировщик задач вносит свои «коррективы».

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

    Заключение

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

    Кэш - встроенная в процессор память, в которую записываются наиболее часто используемые данные (команды) оперативной памяти, что существенно ускоряет работу.

    Объем кэша L1 (от 8 до 128 Кб)
    Объем кэш-памяти первого уровня.
    Кэш-память первого уровня - это блок высокоскоростной памяти, расположенный прямо на ядре процессора.
    В него копируются данные, извлеченные из оперативной памяти.

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

    Емкость кэш-памяти первого уровня невелика и исчисляется килобайтами.
    Обычно «старшие» модели процессоров обладают большим объемом кэша L1.
    Для многоядерных моделей указывается объем кэш-памяти первого уровня для одного ядра.

    Объем кэша L2 (от 128 до 12288 Кб)
    Объем кэш-памяти второго уровня.
    Кэш-память второго уровня - это блок высокоскоростной памяти, выполняющий те же функции, что и кэш L1 (см. «Объем кэша L1»), однако имеющий более низкую скорость и больший объем.

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

    Объем кэша L3 (от 0 до 16384 Кб)
    Объем кэш-памяти третьего уровня.
    Интегрированная кэш-память L3 в сочетании с быстрой системной шиной формирует высокоскоростной канал обмена данными с системной памятью.

    Как правило, кэш-памятью третьего уровня комплектуются только CPU для серверных решений или специальные редакции «настольных» процессоров.

    Кэш-памятью третьего уровня обладают, например, такие линейки процессоров, как Intel Pentium 4 Extreme Edition, Xeon DP, Itanium 2, Xeon MP и прочие.

    Twin BiCS FLASH - новая технология трехмерной флэш-памяти

    11 декабря 2019 г. на Международном совещании по электронным устройствам (IEDM) IEEE корпорация TOKYO-Kioxia анонсировала технологию трехмерной флэш-памяти - Twin BiCS FLASH.

    Драйвер AMD Radeon Software Adrenalin Edition 2020 19.12.2 WHQL (добавлено)

    10 декабря компания AMD представила мега драйвер Radeon Software Adrenalin 2020 Edition 19.12.2 WHQL.

    Накопительное обновление Windows 10 1909 KB4530684

    10 декабря 2019 г. Microsoft выпустила накопительное обновление KB4530684 (Build 18363.535) для Windows 10 November 2019 Update (версия 1909) на базе процессоров x86, x64 (amd64), ARM64 и Windows Server 2019 (1909) для систем на базе процессоров x64.

    Драйвер NVIDIA Game Ready GeForce 441.66 WHQL

    Драйвер NVIDIA GeForce Game Ready 441.66 WHQL включает поддержку игр MechWarrior 5: Mercenaries и Detroit: Become Human, а также добавляет поддержку G-SYNC мониторов MSI MAG251RX и ViewSonic XG270.

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

    Только потом они отправляются непосредственно в процессор. Все это занимает очень много времени по компьютерным меркам. А вот, что если бы данные хранились где-то рядом с процессором?

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

    Назначение кеш памяти

    Что же такое кэш-память или кэш (по англ. cache memory, cache):

    В широком смысле, подразумевается любая память с быстрым доступом , где хранится часть данных с другого носителя с более медленным доступом;

    В узком смысле - это сверхоперативный вид памяти, который используется для повышения скорости доступа микропроцессора к оперативной памяти.

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

    Когда этот человек прочитал книгу, то она обратно возвращается на полку. И если уже любой другой человек приходит и просит эту же самую книгу, цикл повторяется снова.

    Вот пример того, как библиотека, то есть система работает без кэш-памяти .

    Зачем нужна кэш-память?

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

    Но, когда книга вернулась, библиотекарь не возвращает ее на полку, а кладет в ящик стола (этакая местная оперативная кэш-память ).

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

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

    Хранит ли кэш только часто используемые данные? Как функционирует и работает кэш оперативной памяти ?

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

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

    Аналогичным образом, когда кэш-память извлекает запрошенные данные из памяти, она также извлекает данные, которые находятся по адресам, близким к запрошенным.

    Эти смежные блоки данных, которые и передаются в кэш, называются кэш-линиями. Подробнее о понятии кэш-памяти можно посмотреть в этом видео:

    Уровни кэш памяти

    Большинство жестких дисков используют один уровень кэш-памяти . Но кэш имеет два уровня, где уровень L1 меньше и быстрее, а уровень L2, несколько медленнее (но все равно быстрее, чем основная внутренняя память ).

    Лучшая бесплатная программа HDDScan для проверки жестких дисков

    И снова возвратимся за примером к нашей библиотеке, на примере ее работы становится понятна как работает внешняя память компьютера .

    Рассмотрим ящик библиотекаря в качестве кэша L1. Когда спрос на книги высок, и в ящике уже довольно много книг (нет места складывать) и вероятность того, что там найдется нужная, снижается.

    Память L2 кэш

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

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

    Двухуровневый кэш процессора

    Кэш двух уровней у процессора – хорошая идея? Безусловно, да.

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

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

    Но если кэш-память работает так быстро, почему бы не выполнять его достаточно большой, чтобы хранить все данные оперативной памяти в нем?

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

    Хотя в последнее время, размеры кэш-памяти все увеличиваются, а цены растут не сильно, поэтому компьютеры работают все быстрее и быстрее.

    То есть, наш библиотекарь обзаводится ящиком стола все большего размера, а шкафчик, стоящий рядом становится более вместительным! Еще в тему - двухядерные процессоры - правильно конфигурируем Windows.

    Кэширование жесткого диска

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

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

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

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

    2. Поскольку при движении головка вибрирует, то необходимо немного времени, чтобы она успокоилась.

    3. Наконец, требуется время, чтобы головка нашла искомый сектор.

    Методы кэширования, используемые для оперативной памяти, применяются и для кэширования информации, хранимой на жестких дисках.

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

    Этот метод известен также как метод опережающего чтения (Read Ahead). При работе с многозадачными системами желательно иметь жесткий дик (винчестер) с мультисегментной кэш-памятью, которая для каждой из задач отводит свою часть кэша.

    Кстати, если у вас недостаточно знаний о том, как лучше просканировать и протестировать жесткий диск , то обязательно посмотрите
    подробный и бесплатный виде-оурок на эту тему:
    как проверить винчестер на работоспособность

    Кэш-память процессора

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

    Кэш-память процессора на компьютере выполняет функции буфера между процессором и оперативной памятью.

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

    Кэш-памяти процессора делятся на несколько видов:

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

    Работает эта память на частоте процессора. Время доступа к ней существенно меньше, чем к данным в основной оперативной памяти. Этим достигается ускорение работы процессора.

    Cache L2 - «кэш-память второго уровня». Это промежуточная сверхоперативная память, которая имеет быстродействие ниже памяти первого уровня, но выше основной оперативной памяти. Ее размер обычно составляет от нескольких сотен килобайт до нескольких мегабайт.

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


    Секреты и тонкости работы на компьютере

    Понравилась статья? Поделитесь ей