Чи є процесори, які виконують цю можливу оптимізацію запису кешу L1?


9

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

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

Моє запитання: чи є процесори, які виконують цю оптимізацію?

Передумови, чому я запитую: я пишу якийсь код, який повинен мати постійний доступ до пам'яті; тобто хтось, хто вміє слухати поведінку кеша, не повинен мати змогу виводити те, що я роблю. Деякі мої звернення - це записи, і, очевидно, для реалізації цього коду, багато записів будуть писати ті самі дані, які вже є. Мені потрібно робити записи, тому що, залежно від даних, дані, які я записую, можуть бути або не бути однаковими, і важливо виконувати ті самі дії незалежно. Якщо центральний процесор оптимізує насправді не записуючи "без зміни запису", це означатиме, що поведінка кешу буде змінюватися залежно від того, що я роблю, що підриває мою мету.

Отже, чи є процесор, який намагається оптимізувати запис таким чином?


11
Кажуть, що в інформатиці є дві по-справжньому важкі проблеми: відключення кешу, іменування речей і помилки, що не входять в один. Це приклад того, чому перша з них хитра.
Мейсон Уілер

@poncho ви говорите, що "той, хто вміє слухати поведінку кешу, не повинен мати змогу виводити те, що я роблю". Тепер, якщо деякі процесори реалізували цю функцію "розумного повернення", яка не скасовує кеш, якщо дані дійсно не оновлюються, то, відправившись один рівень далі від центрального процесора в ієрархії пам'яті, можна було б спостерігати за трафіком / термінами відмінності між реальним записом і манекеном. Це те, що вас хвилює?
TheCodeArtist

@poncho Крім того, ваше справжнє питання стосується впровадження кращого привілейованого / безпечного режиму, який не просочує інформацію про використання. Можливо, вам слід це запитати? ...
TheCodeArtist

1
@TheCodeArtist: добре, були опубліковані криптографічні атаки бічних каналів, де програма розповсюдження може бути атакована іншою програмою, що працює на іншому ядрі того ж центрального процесора, за допомогою програми атаки контролювати спільний кеш. Я вважаю, що така програма може потенційно виявити, чи були лінії кеш-пам'яті L1 промиті, і, отже, могла б вивести інформацію про програму, яка мене зацікавила, якщо ЦП здійснить оптимізацію, що обговорюється. Я не говорю про "безпечний режим", оскільки я не припускаю можливості змінювати процесор або ОС.
пончо

4
Навіть якщо це справді сьогодні, це не гарантовано, що це буде завтра.
pjc50

Відповіді:


4

За години пошуку я не зміг знайти процесор, який використовує цю специфічну оптимізацію. Більшість згаданих оптимізацій, як правило, стосуються удару / пропуску за допомогою операцій читання / запису та доступу до даних:

(сторінки 7 та) https://cseweb.ucsd.edu/classes/fa14/cse240A-a/pdf/08/CSE240A-MBT-L15-Cache.ppt.pdf

Однак це не означає, що цю оптимізацію неможливо здійснити. Взагалі, можна програмно отримати доступ до розміру кеш-лінії CPU. Також можна отримати доступ до поточних значень в регістрах кешу, але це дещо небезпечно. Якщо ви отримаєте неправильні регістри в поганий час, ви можете підробити ті, що стосуються запущеної програми. Або ви могли ненавмисно змінити вміст рядків, які ви намагаєтеся прочитати.

Отримання поточного значення в кеші реєстру

Крім того, всі теоретичні рішення потребують певної форми реалізації програмного забезпечення (асемблера). Найближче, що я знайшов, стосується архітектури ARM, яка, можливо, дозволяє керувати кешем. На додаток до цього, ви також повинні знати розмір лінії кешу для потрібного процесора. Ви можете уважно прочитати вміст кешу до другого місця в пам'яті, з кроком розміру рядків, і порівняти його з даними, які збираються записати в регістри (або в цьому випадку рядки кешу L1).

Прочитайте вміст кешу CPU

Звідти ви могли б розробити програмну систему, що запобігає однакові переписування. Хоча це трохи спрощено, це так, тому що рішення повинно бути застосовне до будь-якого ЦП, який існує.

Ще одна можливість, яку я знайшов, пов'язану з узгодженістю кешу:

Відповідний уривок із статті Вікіпедії про тісну узгодженість

Основним моментом, який привернув мою увагу, стосовно цього питання, був опис Snarfing:

Це механізм, коли кеш-контролер спостерігає за адресою та даними, намагаючись оновити власну копію місця в пам'яті, коли другий ведучий модифікує місце в основній пам'яті. Коли спостерігається операція запису до місця, в якому кеш має копію, контролер кешу оновлює свою власну копію місця прискореної пам’яті новими даними.

Іншими словами, можливо, вже існують механізми. Просто вони можуть не використовуватися для запропонованої вами оптимізації. Вам доведеться реалізувати програмне забезпечення, яке виконувало порівняння читання / запис.


Також можна отримати доступ до поточних значень в регістрах кешу, але це дещо небезпечно. Так, це не має сенсу. Ви маєте на увазі регістри процесора? Компілятор, створений або власноруч написаний код ASM, використовує регістри для зберігання значень, на яких він працює ...
Peter Cordes

Якщо ви намагаєтесь реалізувати це в програмному забезпеченні, вам просто знадобиться код генератора компілятора, який не if (mem != x) { mem = x; }замість цього mem = x;. Це лише іноді оптимізація спільних ліній кешу в багатопотоковій програмі, оскільки запис заважає читати інші потоки.
Пітер Кордес

1
"snarfing" не має нічого спільного з цим. Це просто пасивне сопіння. Кешові процесори використовують MESI, щоб вони могли мати цілісні кешовані записи.
Пітер Кордес

@PeterCordes Якщо ви вважаєте, що моя відповідь неприємна, я прошу вибачення. Однак, здається, ви маєте більше розуміння, ніж я, з цього питання. Отже, чому б не відповісти на запитання самостійно? Моя відповідь була, очевидно, неадекватною вашим стандартам ...


3

Запис у кеш-пам'ять L1 - дуже важлива за часом операція.

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

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

Зазвичай це не так у сучасному процесорі. Дані, які потрібно записати, можливо, все ж обчислюються, наприклад. Кеш все ще може продовжувати, завантажувати кеш-рядок, якщо потрібно, позначити рядок кешу як змінений тощо, навіть до того, як обчислення буде закінчено. Весь облік книг вже може бути виконаний, за винятком фактичної модифікації кеш-лінії. Якщо ви хочете порівняти нещодавно записані результати та старі дані кеш-рядка, це неможливо.

Наприклад, якщо у вас є код C a [i] = x / y; поділ x / y займає надзвичайно багато часу для роботи на більшості процесорів. Однак більша частина роботи, необхідної для збереження результату до [i], відбулася задовго до закінчення поділу; єдине, чого не вистачає, - це переміщення восьми байтів результатів до рядка кешу. Операція, що промиває рядок кеша, автоматично чекає, поки ділення закінчиться. Операція зчитування [i], ймовірно, буде перенаправлена, щоб отримати результат прямо з дільника.


Кеш, що використовує MESI для узгодженості, все ще може зробити RFO, але якщо дані порівняли те саме, коли вони були готові, залиште рядок у ексклюзивному стані замість модифікованого. Справжня причина, яку це не робиться в апаратному забезпеченні, полягає в тому, що це коштує додаткового зчитування кешу, оскільки дані зобов’язуються кешувати, і вимагає свого роду атомний цикл читання / порівняння / запису (з додатковою установкою брудного біта), що змушує його смоктати конвеєрна реалізація.
Пітер Кордес

1

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

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

Отже, насправді оптимізація зараз буде залежати від дуже розпливчастого чинника: скільки разів середнє програмне забезпечення переписує кеш-пам’ять з тими ж даними.


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

@ziggystar Ну, я не майстер обладнання, але я звик до думки, що все йде з вартістю. Так само порівнюйте операцію з лінією кешу. Це може бути швидким. Але це все-таки коштує. І я думаю, що виконавці вирішили не платити за це. Можливо, навіть після певного роздуму та вимірювання.
Владислав Раструсний

1
Але ви говорите про час, коли вартість може бути лише збільшенням кількості воріт.
ziggystar

1
@ziggystar: Це не просто ворота. Коли дані надсилаються в кеш, зазвичай процес надсилання даних може позначати рядок кешу як змінений. При цій «оптимізації» старі дані та нові дані повинні пройти через ці ворота, що спричинить деяку затримку, і лише тоді кеш може бути визнаний недійсним. Ви повинні стиснути все це в один процесорний цикл, інакше запис у рядок кешу раптом займає два цикли. А тепер, щоб зробити складніше, подумайте, що відбувається, коли я запишу вісім слів підряд у кеш-рядок.
gnasher729

1
І кожен із цих записів затримує рішення, чи буде змінено рядок кешу. Отже, коли відбувається друге записування, рядок кешу не знає, модифікований він чи ні (поки що). Це буде весело.
gnasher729
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.