XOP — Вікіпедія
XOP (від англ. eXtended Operations – розширені операції [1]) – розширення набору інструкцій x86/AMD64, анонсоване корпорацією AMD 1 травня 2009 року.
Є розширенням та розвитком ідей, реалізованих у 128-бітих інструкціях SSE в архітектурах x86/x86-64. Реалізовано з мікроархітектури мікропроцесорів AMD Bulldozer (12 жовтня 2011).[2] Не підтримується процесорами AMD, починаючи з мікроархітектури Zen (Ryzen, EPIC; 2017 рік)[3].
У набір інструкцій XOP входить кілька різних типів векторних інструкцій, оскільки він був спочатку задуманий як велике оновлення SSE. Більшість інструкцій є цілими, але в набір також входять інструкції для перестановки чисел з рухомої комою та інструкції екстракції дробової частини.
XOP є переробкою частини ідей, призначених для SSE5. Набір було змінено, щоб зробити його більш схожим на AVX, але не дублювати інструкції. Інструкції, що збігаються з AVX, були видалені або переміщені в окремі розширення, наприклад FMA4 (векторне множення-додавання для рухомої коми) і CVT16 (перетворення чисел половинної-точності, реалізовано корпорацією Intel як F16C).[1]
Усі інструкції SSE5, для яких був аналог або еквівалент у наборах AVX та FMA3, використовують кодування, запропоновані корпорацією Intel. Цілочисленні інструкції без еквівалентів AVX були класифіковані як розширення XOP.[1] Інструкції XOP кодуються кодами операцій, що починаються з байта 0x8F (шістнадцяткове значення), але в іншому використовують схему кодування, майже ідентичну AVX з 3-байтовим префіксом VEX.
Окремі експерти (Agner Fog)[4] розцінили це як ознака того, що корпорація Intel не дозволила AMD використовувати будь-яку частину великого кодового простору VEX. Компанія AMD, ймовірно, була змушена використовувати відмінні коди для того, щоб уникнути будь-якої комбінації, яку міг би в майбутньому використовувати Intel. Схема кодування XOP максимально наближена до VEX, але усуває ризик перетину майбутніх опкодів Intel.
Використання байта 8F вимагає, щоб m-біт (див. схема кодування VEX) мав значення більше або дорівнює 8, щоб уникнути перетину з інструкціями, визначеними на даний момент. Байт 0xC4, який використовується у схемі VEX не має такого обмеження. Через це використання m-бітів для інших цілей у майбутньому в XOP схемі може бути утруднено (VEX не має обмежень на m-біти). Інша можлива проблема полягає в тому, що біти pp в XOP завжди мають значення 00, у той час як у VEX вони встановлюються значення 01 для вказівки, що в інструкції немає застарілих еквівалентів. Це може ускладнити використання pp бітів для інших цілей у майбутньому.
Аналогічна проблема сумісності - відмінності реалізацій розширень FMA3 та FMA4. Intel спочатку запропонував розширення FMA4 в рамках специфікації AVX/FMA версії 3, щоб замінити 3-операнди варіант FMA, запропонований AMD в SSE5. Після того як AMD реалізувала FMA4, Intel відмовився від FMA4 і повернувся до FMA3 у 5 версії специфікації AVX/FMA.[1][5][6]
У березні 2015 року компанія AMD розкрила в описі патча для пакету GNU Binutils що Zen, третє покоління архітектури x86-64, у першій редакції (znver1 — Zen, версія 1), не підтримуватиме TBM, FMA4, XOP and LWP інструкції, розроблені спеціально для сімейства мікроархітектури «Bulldozer».[7][8]
Ці інструкції є цілим аналогом наборів інструкцій FMA. Всі вони — чотириоперадні інструкції, схожі на FMA4, і всі вони працюють над знаковими цілими числами.
Інструкція | Опис[9] | Операція |
---|---|---|
VPMACSWW
| Multiply Accumulate (with Saturation) Word to Word | 2x8 words (a0-a7, b0-b7) + 8 words (c0-c7) → 4 words (r0-r7) r0 = a0 * b0 + c0, r1 = a1 * b1 + c1, .. |
VPMACSWD
| Multiply Accumulate (with Saturation) Low Word to Doubleword | 2x8 words (a0-a7, b0-b7) + 4 doublewords (c0-c3) → 4 doublewords (r0-r3) r0 = a0 * b0 + c0, r1 = a2 * b2 + c1, .[2] |
VPMACSDD
| Multiply Accumulate (with Saturation) Doubleword to Doubleword | 2x4 doublewords (a0-a3, b0-b3) + 4 doublewords (c0-c3) → 4 doublewords (r0-r3) r0 = a0 * b0 + c0, r1 = a1 * b1 + c1, .. |
VPMACSDQL
| Multiply Accumulate (with Saturation) Low Doubleword to Quadword | 2x4 doublewords (a0-a3, b0-b3) + 2 quadwords (c0-c1) → 2 quadwords (r0-r3) r0 = a0 * b0 + c0, r1 = a2 * b2 + c1 |
VPMACSDQH
| Multiply Accumulate (with Saturation) High Doubleword to Quadword | 2x4 doublewords (a0-a3, b0-b3) + 2 quadwords (c0-c1) → 2 quadwords (r0-r3) r0 = a1 * b1 + c0, r1 = a3 * b3 + c1 |
VPMADCSWD
| Multiply Add Accumulate (with Saturation) Word to Doubleword | 2x8 words (a0-a7, b0-b7) + 4 doublewords (c0-c3) → 4 doublewords (r0-r3) r0 = a0 * b0 + a1 * b1 + c0, r1 = a2 * b2 + a3 * b3 + c1, .. |
Інструкції горизонтального додавання додають суміжні значення у вхідному векторі одне до одного. Вихідний розмір у наведених нижче інструкціях описує ширину виконаного горизонтального додавання. Наприклад, горизонтальний «байт у слова» додає по два байти за раз і повертає результат у вигляді вектора слів, але «байт у четверне слово» додає вісім байтів разом і повертає результат у вигляді вектора чотирьох слів. Шість додаткових горизонтальних інструкцій додавання та віднімання можна знайти в SSSE3, але вони працюють з двома вхідними векторами і виконують лише дві операції.
Інструкція | Опис[9] | Операція |
---|---|---|
VPHADDBW
| Horizontal add two signed/unsigned bytes to word | 16 bytes (a0-a15) → 8 words (r0-r7) r0 = a0+a1, r1 = a2+a3, r2 = a4+a5, … |
VPHADDBD
| Horizontal add four signed/unsigned bytes to doubleword | 16 bytes (a0-a15) → 4 doublewords (r0-r3) r0 = a0+a1+a2+a3, r1 = a4+a5+a6+a7, … |
VPHADDBQ
| Horizontal add eight signed/unsigned bytes to quadword | 16 bytes (a0-a15) → 2 quadwords (r0-r1) r0 = a0+a1+a2+a3+a4+a5+a6+a7, … |
VPHADDWD
| Horizontal add two signed/unsigned words to doubleword | 8 words (a0-a7) → 4 doublewords (r0-r3) r0 = a0+a1, r1 = a2+a3, r2 = a4+a5, … |
VPHADDWQ
| Horizontal add four signed/unsigned words to quadword | 8 words (a0-a7) → 2 quadwords (r0-r1) r0 = a0+a1+a2+a3, r1 = a4+a5+a6+a7 |
VPHADDDQ
| Horizontal add two signed/unsigned doublewords to quadword | 4 doublewords (a0-a3) → 2 quadwords (r0-r1) r0 = a0+a1, r1 = a2+a3 |
VPHSUBBW | Horizontal subtract two signed bytes to word | 16 bytes (a0-a15) → 8 words (r0-r7) r0 = a0-a1, r1 = a2-a3, r2 = a4-a5, … |
VPHSUBWD | Horizontal subtract two signed words to doubleword | 8 words (a0-a7) → 4 doublewords (r0-r3) r0 = a0-a1, r1 = a2-a3, r2 = a4-a5, … |
VPHSUBDQ | Horizontal subtract two signed doublewords to quadword | 4 doublewords (a0-a3) → 2 quadwords (r0-r1) r0 = a0-a1, r1 = a2-a3 |
Цей набір векторних інструкцій використовує поле immediate кодування як додатковий аргумент, який визначає яке саме порівняння виконувати. Існує вісім можливих варіантів порівняння для кожної інструкції. Вектори порівнюються і всі порівняння, що виявилися істинними, встановлюють всі біти у відповідному регістрі призначення в 1, а помилкові порівняння - встановлюють біти в 0. Цей результат може бути безпосередньо використаний в інструкції VPCMOV - векторизованого умовного пересилання.
Інструкція | Опис[9] | immediate | Порівняння |
---|---|---|---|
VPCOMB | Compare Vector Signed Bytes | 000 | Менше |
VPCOMW | Compare Vector Signed Words | 001 | Менше або дорівнює |
VPCOMD | Compare Vector Signed Doublewords | 010 | Більше |
VPCOMQ | Compare Vector Signed Quadwords | 011 | Більше ніж або дорівнює |
VPCOMUB | Compare Vector Unsigned Bytes | 100 | Дорівнює |
VPCOMUW | Compare Vector Unsigned Words | 101 | Не дорівнює |
VPCOMUD | Compare Vector Unsigned Doublewords | 110 | Завжди брехливе |
VPCOMUQ | Compare Vector Unsigned Quadwords | 111 | Завжди істинне |
VPCMOV працює як побітовий варіант інструкцій blend із SSE4. Для кожного біта операнда-селектора, рівного 1, виділяє підсумковий біт з першого джерела, якщо біт у селекторі дорівнює 0, вибирає підсумковий біт з другого джерела. При використанні спільно з векторними операціями порівняння XOP дозволяє реалізувати векторний тернарний оператор, або якщо в ролі другого аргументу виступає регістр призначення, умовне умовне пересилання (CMOV).
Інструкція | Опис[9] |
---|---|
VPCMOV | Vector Conditional Move |
Інструкції зсуву відрізняються від подібних до набору інструкцій SSE2 в тому, що вони можуть зрушувати кожен елемент на різну кількість біт, використовуючи знакові цілі числа, що упаковані, з векторного регістра. Знак вказує напрямок зсуву або повороту, позитивні значення для зсуву вліво і негативні - для зсуву вправо [10] Корпорація Intel реалізувала інший, несумісний набір змінних векторних зсувів та поворотів а AVX2.[11]
Інструкція | Опис[9] |
---|---|
VPROTB | Packed Rotate Bytes |
VPROTW | Packed Rotate Words |
VPROTD | Packed Rotate Doublewords |
VPROTQ | Packed Rotate Quadwords |
VPSHAB | Packed Shift Arithmetic Bytes |
VPSHAW | Packed Shift Arithmetic Words |
VPSHAD | Packed Shift Arithmetic Doublewords |
VPSHAQ | Packed Shift Arithmetic Quadwords |
VPSHLB | Packed Shift Logical Bytes |
VPSHLW | Packed Shift Logical Words |
VPSHLD | Packed Shift Logical Doublewords |
VPSHLQ | Packed Shift Logical Quadwords |
VPPERM — єдина інструкція, яка поєднує інструкції PALIGNR і PSHUFB з SSSE3 і розширює їх. Деякі порівнюють її з AltiVec інструкцією VPERM.[12] Вона приймає три регістри на вхід: два джерела та селектор (третій). Кожен байт у селекторі вибирає один із байтів в одному з двох джерел для запису у вихідний регістр. Селектор може вибирати нульовий байт, змінювати порядок біт на зворотний, повторювати значний біт. Всі ефекти або входи можуть бути інвертовані.
Інструкції VPPERMIL2PD та VPPERMIL2PS – двооперандні варіанти інструкцій VPERMILPD та VPERMILPS з набору AVX. Вони, як і VPPERM, можуть вибрати вихідне значення з будь-яких полів двох вхідних регістрів.
Інструкція | Опис[9] |
---|---|
VPPERM | Packed Permute Byte |
VPPERMIL2PD | Permute Two-Source Double-Precision Floating-Point |
VPPERMIL2PS | Permute Two-Source Single-Precision Floating-Point |
Ці інструкції виділяють дрібну частину з упакованих чисел із рухомою комою. Така частина числа може бути втрачена при перетворенні їх на ціле.
Інструкція | Опис[9] |
---|---|
VPCMOV | Vector Conditional Move |
- ↑ а б в г Dave Christie (7 травня 2009), Striking a balance, AMD Developer blogs, архів оригіналу за 4 листопада 2013, процитовано 4 листопада 2013
- ↑ а б AMD64 Architecture Programmer's Manual Volume 6: 128-Bit and 256-Bit XOP, FMA4 and CVT16 Instructions (PDF), AMD, 1 травня 2009, архів оригіналу (PDF) за 21 серпня 2018, процитовано 20 березня 2022
- ↑ Michael Larabel (3 березня 2017). The Impact Of GCC Zen Compiler Tuning On AMD Ryzen Performance. Phoronix. Архів оригіналу за 14 вересня 2017. Процитовано 20 березня 2022.
But with Zen being a clean-sheet design, there are some instruction set extensions found in Bulldozer processors not found in Zen/znver1. Those no longer present include FMA4 and XOP.
- ↑ Stop the instruction set war, Agner Fog, 5 грудня 2009, архів оригіналу за 12 травня 2022, процитовано 20 березня 2022
- ↑ Intel AVX Programming Reference (PDF), March 2008, архів оригіналу (PDF) за 7 серпня 2011, процитовано 17 січня 2012 [Архівовано 2011-08-07 у Wayback Machine.]
- ↑ Intel Advanced Vector Extensions Programming Reference, January 2009, архів оригіналу за 29 лютого 2012, процитовано 17 січня 2012
- ↑ Ganesh Gopalasubramanian (10 березня 2015). [PATCH] add znver1 processor. [email protected] (Список розсилки). Архів оригіналу за 4 березня 2016. Процитовано 20 березня 2022.
- ↑ Amit Pawar (7 серпня 2015). [PATCH] Remove CpuFMA4 From Znver1 CPU Flags. [email protected] (Список розсилки). Архів оригіналу за 7 березня 2016. Процитовано 20 березня 2022.
- ↑ а б в г д е ж AMD64 Architecture Programmer's Manual, Volume4: 128-Bit and 256-Bit Media Instructions (PDF). AMD. Архів оригіналу (PDF) за 14 листопада 2021. Процитовано 13 січня 2014.
- ↑ New "Bulldozer" and "Piledriver" Instructions (PDF). AMD. Архів оригіналу (PDF) за 7 січня 2013. Процитовано 13 січня 2014.
- ↑ Intel Architecture Instruction Set Extensions Programming Reference. Intel. Архів оригіналу (PDF) за 1 лютого 2014. Процитовано 29 січня 2014.
- ↑ Buldozer x264 optimisations. Архів оригіналу за 15 січня 2014. Процитовано 13 січня 2014. [Архівовано 2014-01-15 у Wayback Machine.]