Друкарня від WE.UA

Важливість розуміння когерентності кешу для розробників

Вступ

Когерентність(узгодженість, взаємопов’язаність) кешу - концепція, що має свої коріння у глибині проектування апаратного забезпечення, - часто може бути складною темою для комп'ютерних інженерів. Проте глибоке розуміння цієї теми не тільки розкриває більш глибоке розуміння принципів проектування систем, але й приносить суттєву користь розробникам програмного забезпечення. Тож чому розробники програмного забезпечення повинні витрачати час на розуміння конструкції кешу ЦП і, зокрема, узгодженості кешу?

Когарентність кешу: більше, ніж просто питання апаратного забезпечення

Багато принципів, отриманих вивченням взаємопов'язаності кешу, мають пряме застосування у сферах розробки програмного забезпечення, таких як архітектура розподілених систем та рівні ізоляції баз даних. Розуміння, як узгодженість реалізована у апаратних кешах, може покращити розуміння концепцій eventual and strong consistency, особливо як вони відносяться до синхронізації даних в розподілених системах.

Засвоєння принципів взаємопов'язаності кешу може допомогти уникнути помилкових уявлень про багатопоточне програмування. Однак, важливо зазначити, що навіть одноядерні системи можуть бути вразливі до помилок конкурентності, якщо не використовуються відповідні конструкції для синхронізації.

Щодо волатильних змінних у мовах, таких як Java, важливо зрозуміти, що вони гарантують, що оновлення будуть видимі для всіх потоків негайно. Це не обов'язково означає, що вони "запобігають кешуванню спільних даних локально" або змушують їх "читати/записувати безпосередньо в основну пам'ять", як це помилково можуть вважати деякі розробники. Читання волатильних змінних (у Java) часто не відрізняється вартістю від посилання на кеш L1.

Протоколи взаємопов'язаності кешу. Огляд

Апаратні кеші на сучасних процесорах x86 синхронізуються за допомогою складних протоколів, що забезпечують узгодженість між всіма потоками. Один з широко використовуваних протоколів - це протокол MESI (Modified, Exclusive, Shared, Invalid). Стан даних у кеші може перебувати у будь-якому з цих чотирьох станів.

Modified (M): Дані були змінені і відрізняються від основної пам'яті. Exclusive (E): Дані не були змінені і синхронізовані з основною пам'яттю. Shared (S): Дані не були змінені і синхронізовані з іншими даними. Invalid (I): Дані застарілі і не повинні використовуватися.

Протокол MESI забезпечує, що якщо два різні потоки будь-де в системі зчитують дані з однієї і тієї ж адреси пам'яті, вони ніколи одночасно не зчитують різні значення. Ця послідовність зберігається навіть у випадку, коли потоки хочуть записувати до однієї адреси або зчитувати з однієї адреси.

Більш детальний опис роботи протоколу MESI

Давайте розглянемо протокол MESI у прикладі з процесором, що має чотири ядра (кожне з яких оснащене власним кешем L1) та глобальним кешем L2, які приймають участь в записі та зчитуванні даних.

Припустимо, що потік на ядрі-1 бажає записати дані за адресою 0xabcd. Якщо кеш L1-1 вже містить ці дані, то відбувається "попадання в кеш" (cache hit), і запис відбувається безпосередньо. Однак, якщо дані відсутні в L1-1 або знаходяться в стані Shared, кеш L1-1 надсилає запит на отримання власності (Request-For-Ownership) до кешу L2. Це означає, що кеш L2 отримує ексклюзивний доступ до цих даних, і всі інші копії даних в інших кешах стають недійсними.

Кеш L2 відповідає за координацію взаємодії між кешами L1, забезпечуючи когерентність даних і відстежуючи, які кеші мають дійсні копії даних.

Схожий процес відбувається при зчитуванні даних. Якщо дані не присутні в кеші L1, відбувається "промах кешу" (cache miss), і система здійснює пошук даних у кеші L2 або, у разі необхідності, в глобальній пам'яті. Кеш L2 допомагає керувати когерентністю даних між кешами L1.

Цей приклад є спрощеним представленням роботи протоколу MESI. На практиці, існує багато інших сценаріїв та варіацій, що враховують більш складні аспекти роботи процесора та кеш-пам'яті. Також важливо зазначити, що MESI - це лише один з протоколів когерентності кешу, існують також MOESI, MSI, Illinois, та інші.


  • "L1" вказує на тип кешу - кеш першого рівня. Процесори часто використовують кілька рівнів кешу, зазвичай відмічені як L1, L2, і т.д., де L1 - це найшвидший і найближчий до ядра кеш, а L2, L3 і так далі є дещо повільнішими і “віддаленими“.

  • "-1" вказує на конкретне ядро процесора. У багатоядерних системах кожне ядро має власний кеш L1, тому "-1" позначає кеш L1 першого ядра. Для інших ядер це могло б бути L1-2, L1-3, L1-4 і так далі, в залежності від номера ядра.

Волатильні змінні та регістри

Незважаючи на узгодженість кешів, нам все ще потрібні конструкції, такі як волатильні змінні, у мовах програмування, таких як Java. Це тому, що дані, які зчитуються до регістрів процесора, не обов'язково синхронізуються з даними у кеші або пам'яті. Компілятори і процесори часто роблять оптимізації з припущенням, що код буде виконуватись в однопотоковому режимі, та можуть переставляти інструкції для покращення продуктивності.

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


  1. https://docs.oracle.com/javase/tutorial/essential/concurrency

  2. https://stackoverflow.com/questions/tagged/concurrency

  3. https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

  4. https://docs.oracle.com/javase/specs/jls/se20/jls20.pdf, Див. розділ 17.4, "Memory Model" для подробиць про багатопотоковість в Java.

  5. https://software.rajivprab.com/2018/04/29/myths-programmers-believe-about-cpu-caches/ — В основному, це переклад цієї статті, з доповненням зі вказаних ресурсів

  6. https://www.youtube.com/watch?v=r_ZE1XVT8Ao (картинка з цього відео)

Статті про вітчизняний бізнес та цікавих людей:

  • Вітаємо з Різдвом Христовим!

    Друкарня та платформа WE.UA вітають всіх наших читачів та авторів зі світлим святом Різдва! Зичимо всім українцям довгожданого миру, міцного здоровʼя, злагоди, родинного затишку та втілення всього доброго і прекрасного, чого вам побажали колядники!

    Теми цього довгочиту:

    Різдво
  • Каблучки – прикраси, які варто купувати

    Ювелірні вироби – це не тільки спосіб витратити гроші, але і зробити вигідні інвестиції. Бо вартість ювелірних виробів з кожним роком тільки зростає. Тому купуючи стильні прикраси, ви вигідно вкладаєте кошти.

    Теми цього довгочиту:

    Як Вибрати Каблучку
  • П'ять помилок у виборі домашнього текстилю, які псують комфорт сну

    Навіть ідеальний матрац не компенсує дискомфорт, якщо текстиль підібрано неправильно. Постільна білизна безпосередньо впливає на терморегуляцію, стан шкіри та глибину сну. Більшість проблем виникає не через низьку якість виробів, а через вибір матеріалів та подальшу експлуатацію

    Теми цього довгочиту:

    Домашній Текстиль
  • Як знайти житло в Києві

    Переїжджаєте до Києва і шукаєте житло? Дізнайтеся, як орендувати чи купити квартиру, перевірити власника та знайти варіанти, про які зазвичай не говорять.

    Теми цього довгочиту:

    Агентство Нерухомості
  • Як заохотити дитину до читання?

    Як залучити до читання сучасну молодь - поради та факти. Користь читання для дітей - основні переваги. Розвиток дітей - це наше майбутнє.

    Теми цього довгочиту:

    Читання
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Oleksandr Klymenko
Oleksandr Klymenko@overpathz

Java Software Engineer

7.5KПрочитань
1Автори
95Читачі
На Друкарні з 19 квітня

Більше від автора

Це також може зацікавити:

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Це також може зацікавити: