Яке значення має "не тимчасовий" доступ до пам'яті у x86


123

Це дещо низьке питання. У складі x86 є дві інструкції SSE:

MOVDQA xmmi, m128

і

MOVNTDQA xmmi, m128

Керівництво для IA-32 Software Developer каже , що NT в MOVNTDQA означає Non-Temporal , і що в іншому випадку це те ж саме , як MOVDQA.

Моє запитання: що означає Нетемпоральне ?


6
Зауважте, що SSE4.1 MOVNTDQA xmmi, m128- це навантаження NT, тоді як усі інші інструкції NT зберігаються, за винятком prefetchnta. Тут прийнята відповідь лише говорить про магазини. Це те, що мені вдалося з'ясувати щодо NT-навантажень . TL: DR: сподіваємось, процесор робить щось корисне з підказкою NT, щоб мінімізувати забруднення кешу, але вони не перекривають сильно впорядковану семантику "нормальної" пам'яті WB, тому їм доведеться використовувати кеш.
Пітер Кордес

5
Оновлення: завантаження NT може не принести нічого корисного, окрім регіонів пам'яті UCSW на більшості процесорів (наприклад, сімейство Intel SnB). Хоча NT / потокові магазини, безумовно, працюють на нормальній пам'яті.
Пітер Кордес

4
@Peter: Ви маєте на увазі пам'ять USWC правильно? Я ніколи раніше не чув про UCSW або USWC пам'яті. Погуглити неправильну абревіатуру не було корисно :-)
Ендрю Бейнбрідж

4
@AndrewBainbridge: Так, атрибут типу пам'яті WC. Неспішне спекулятивне записування-поєднання. Я думаю, що я використовував великі літери UnCacheable і пам’ятав, що це повинно бути довжиною 4 літери. : P
Пітер Кордес

Відповіді:


147

Нетемпоральні інструкції SSE (MOVNTI, MOVNTQ тощо) не відповідають нормальним правилам кеш-когерентності. Тому для тимчасових магазинів слід дотримуватися інструкції SFENCE, щоб їх результати своєчасно бачили інші процесори.

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

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

Джерело: http://lwn.net/Articles/255364/


15
Хороша відповідь, я просто хотів би зазначити, що для типу процесора з NT-інструкціями, навіть із не-тимчасовою інструкцією (тобто звичайною інструкцією), кешовий рядок не "читається і не змінюється". Для звичайного запису інструкцій до рядка, який не знаходиться в кеші, рядок зарезервовано в кеші, а маска вказує, які частини рядка оновлені. Ця веб-сторінка називає її "без зупинок у магазині": ptlsim.org/Documentation/html/node30.html . Я не міг знайти більш точні посилання, я чув про це лише від хлопців, завдання яких - реалізація тренажерів процесорів.
Паскаль Куок

2
Насправді ptlsim.org - це веб-сайт про симулятор процесорів, що відрізняється точністю до циклу, саме таку саму річ, яку роблять хлопці, які розповіли мені про "без стійла в магазині". Я також краще згадую їх, якщо вони коли-небудь побачать цей коментар: unisim.org
Паскаль Куок

1
З відповідей та коментарів тут stackoverflow.com/questions/44864033/…, мабуть, SFENCEне потрібно. Принаймні в одній нитці. Чи можете ви також подивитись?
Серж Рогач

1
@SergeRogatch це залежить від сценарію, про який ви говорите, але так, існують сценарії, коли sfenceце потрібно для магазинів NT, тоді як це ніколи не потрібно лише для звичайних магазинів. NT-магазини не упорядковуються стосовно інших магазинів (NT чи ні), як видно з інших потоків , без анкети sfence. Однак для читань із тієї самої нитки, що і магазини, вам ніколи не знадобиться sfence: даний потік завжди побачить власні магазини в програмному порядку, незалежно від того, вони є магазинами NT чи ні.
BeeOnRope

40

Espo в значній мірі вдарив по цілях. Просто хотів додати два мої центи:

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

Я трохи скептично налаштований на ручну систему, що використовує інструкції з кешування кешу. На мій досвід, ці речі призводять до більшої кількості злих помилок, ніж підвищення ефективності.


питання про "вручну кодовану збірку, яка використовує керуючі кеш інструкції". Я знаю, що ви прямо сказали "кодованим вручну", що робити з чимось на кшталт JavaVM. Це кращий варіант використання? JavaVM / Compiler проаналізував статичну та динамічну поведінку програми та використовує ці не тимчасові інструкції.
Пт

4
Використовувати відомі властивості місцевості (або їх відсутність) вашого проблемного домену, алгоритму чи програми не слід уникати. Уникнення забруднення кешу - це дійсно дуже привабливе та ефективне завдання оптимізації. Крім того, чому неприязнь до складання? Існує велика кількість можливостей для отримання вигод, якими компілятор не може скористатися
awdz9nld,

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

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

7

Відповідно до посібника для розробників програмного забезпечення для архітектури Intel® 64 та IA-32, Том 1: Основна архітектура, "Програмування з розширенням SIMD Streaming SIMD (Intel SSE)":

Кешування темпоральних та нечасових даних

Дані, на які посилається програма, можуть бути тимчасовими (дані будуть використані знову) або не тимчасовими (дані будуть посилатися один раз і не використовуватись у найближчому майбутньому). Наприклад, програмний код, як правило, тимчасовий, тоді як мультимедійні дані, такі як список дисплеїв у тривимірній графічній програмі, часто є не тимчасовими. Для ефективного використання кеш-процесорів, як правило, бажано кешувати тимчасові дані, а не кешувати не тимчасові дані. Перевантаження кешів процесора нечасовими даними іноді називають "забрудненням кешів". Інструкції з кешування кеш-пам'яті SSE та SSE2 дозволяють програмі записувати нечасові дані в пам'ять таким чином, що мінімізує забруднення кеш-пам'яті.

Опис нечасного навантаження та інструкції щодо зберігання. Джерело: Інструкції для розробників програмного забезпечення для архітектури Intel 64 та IA-32, Том 2: Посібник з набору інструкцій

ЗАВАНТАЖЕННЯ (MOVNTDQA - Завантажте подвійний чотирисловник, нечасова підказка)

Завантажує подвійний чотирисловник від вихідного операнда (другий операнд) до операнду призначення (перший операнд), використовуючи нечасову підказку, якщо джерелом пам'яті є WC (пам'ять поєднання) типу пам'яті [...]

[...] процесор не зчитує дані в ієрархії кеша, а також не отримує відповідну лінію кешу з пам'яті в ієрархію кешу.

Зауважте, що, як коментує Пітер Кордес, це не корисно для звичайної пам'яті WB (запису) на поточних процесорах, оскільки підказка NT ігнорується (можливо, тому, що немає попередньо встановлених HW-попередників) та повна сильно упорядкована семантика завантаження . prefetchntaможе використовуватися як навантаження, що зменшує забруднення, з пам'яті СБ

МАГАЗИН (MOVNTDQ - зберігати упаковані цілі цілі, використовуючи підказку)

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

[...] процесор не записує дані в ієрархію кешу, а також не отримує відповідну лінію кешу з пам'яті в ієрархію кешу.

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

Нарешті, може бути цікавим переглянути нотатки Джона Макалпіна про магазини, які не є тимчасовими .


3
SSE4.1 MOVNTDQAробить лише все, що є особливим у регіонах пам'яті WC (не підлягає запису), наприклад відео оперативної пам'яті. Це зовсім не корисно для звичайної пам'яті WB (запису) на поточному HW, підказка NT ігнорується і застосовується повна сильно упорядкована семантика навантаження. prefetchntaможе бути корисним, як навантаження, що зменшує забруднення, з пам'яті СБ. Чи підтримують поточні архітектури x86 нетемпоральні навантаження (з "нормальної" пам'яті)? .
Пітер Кордес

2
Це правильно, магазини NT прекрасно працюють на WB-пам’яті і є впорядкованими, і зазвичай є хорошим вибором для запису великих регіонів пам’яті. Але навантаження NT - ні. Посібник x86 на папері дозволяє натяком на NT зробити щось для завантаження з пам'яті WB, але в поточних процесорах він нічого не робить . (Можливо, тому, що не існує префектерів HW, обізнаних про NT.)
Пітер Кордес

Я додав відповідну інформацію до відповіді. Велике спасибі.
chus

1
@LewisKelsey: NT- магазини змінюють тип пам'яті. Ось чому вони можуть бути слабо впорядковані у пам'яті WB. Основним ефектом є уникнення RFO (очевидно, вони надсилають недійсних, що навіть очищає інші брудні лінії, коли вони досягають пам'яті). Вони можуть також стати видимим зіпсований, так що вони не повинні чекати , поки після раніше кеш-промаху (регулярний) магазин фіксацій, або до тих пір , раніше кеш-промах навантаження не отримує дані. тобто про вузьке місце, про яке питають: Чи пам'ять поза кожним ядром завжди концептуально рівна / рівномірна / синхронна в багатопроцесорній системі? .
Пітер Кордес

1
@LewisKelsey: Машина для впорядкування пам’яті очищається, може знищити будь-які вантажі з магазину UC, що не слід було робити раніше, якщо це необхідно. Крім цього, замовлення на здійснення зобов’язань не приймається до виконання, поки магазин не вийде зі складу позакладеного замовлення. Це не може статися, поки після того, як загальна адреса магазину виконана, в цей момент можна перевірити тип пам'яті для адреси. Адреса магазину взагалі перевіряє TLB при його виконанні; ось так процесори можуть виявити несправні магазини, перш ніж вийти на пенсію. Він не може дочекатися, поки запис SB буде готовий взяти на себе зобов'язання L1d; в цей момент виконання минуло його.
Пітер Кордес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.