Одна инструкция, несколько данных ( SIMD ) — тип параллельной обработки в таксономии Флинна . SIMD может быть внутренним (частью аппаратного дизайна) и может быть напрямую доступен через архитектуру набора инструкций (ISA), но его не следует путать с ISA. SIMD описывает компьютеры с несколькими элементами обработки , которые выполняют одну и ту же операцию над несколькими точками данных одновременно.
Такие машины используют параллелизм на уровне данных , но не параллелизм : существуют одновременные (параллельные) вычисления, но каждое устройство выполняет одну и ту же инструкцию в любой момент времени (только с разными данными). SIMD особенно применим к обычным задачам, таким как регулировка контрастности цифрового изображения или регулировка громкости цифрового звука . Большинство современных конструкций ЦП включают инструкции SIMD для повышения производительности использования мультимедиа . SIMD имеет три различных подкатегории в Таксономии Флинна 1972 года , одна из которых — SIMT . SIMT не следует путать с программными потоками или аппаратными потоками , оба из которых являются задачами с разделением времени (временным слайсингом). SIMT — это настоящее одновременное параллельное выполнение на аппаратном уровне.
Современные графические процессоры (GPU) часто представляют собой широкие реализации SIMD. [ необходима цитата ]
Первое использование инструкций SIMD было в компьютере ILLIAC IV , разработка которого была завершена в 1966 году.
SIMD был основой для векторных суперкомпьютеров начала 1970-х годов, таких как CDC Star-100 и Texas Instruments ASC , которые могли работать с «вектором» данных с помощью одной инструкции. Векторная обработка была особенно популяризирована Cray в 1970-х и 1980-х годах. Архитектуры векторной обработки теперь считаются отдельными от SIMD-компьютеров: Таксономия Дункана включает их, тогда как Таксономия Флинна — нет, из-за работы Флинна (1966, 1972), предшествовавшей Cray-1 (1977).
Первая эра современных SIMD-компьютеров характеризовалась массивно-параллельной обработкой -типа суперкомпьютеров , таких как Thinking Machines CM-1 и CM-2 . Эти компьютеры имели много процессоров с ограниченной функциональностью, которые работали параллельно. Например, каждый из 65 536 однобитных процессоров в Thinking Machines CM-2 мог выполнять одну и ту же инструкцию одновременно, позволяя, например, логически объединять 65 536 пар битов за раз, используя сеть, соединенную гиперкубом, или выделенную процессору оперативную память для поиска своих операндов. Суперкомпьютеры отошли от подхода SIMD, когда недорогие скалярные подходы MIMD, основанные на массовых процессорах, таких как Intel i860 XP, стали более мощными, и интерес к SIMD пошел на убыль. [2]
Текущая эра процессоров SIMD выросла из рынка настольных компьютеров, а не из рынка суперкомпьютеров. Поскольку процессоры для настольных компьютеров стали достаточно мощными для поддержки игр в реальном времени и обработки аудио/видео в 1990-х годах, спрос на этот конкретный тип вычислительной мощности вырос, и поставщики микропроцессоров обратились к SIMD, чтобы удовлетворить спрос. [3] Hewlett-Packard представила инструкции MAX в настольных компьютерах PA-RISC 1.1 в 1994 году для ускорения декодирования MPEG. [4] Sun Microsystems представила целочисленные инструкции SIMD в своих расширениях набора инструкций " VIS " в 1995 году в своем микропроцессоре UltraSPARC I. MIPS последовала их примеру со своей аналогичной системой MDMX .
Первая широко распространенная настольная SIMD была с расширениями Intel MMX для архитектуры x86 в 1996 году. Это вызвало появление гораздо более мощной системы AltiVec в системах Motorola PowerPC и IBM POWER . Intel ответила в 1999 году, представив совершенно новую систему SSE . С тех пор было несколько расширений наборов инструкций SIMD для обеих архитектур. Расширенные векторные расширения AVX, AVX2 и AVX-512 разработаны Intel. AMD поддерживает AVX, AVX2 и AVX-512 в своих текущих продуктах. [5]
Все эти разработки были ориентированы на поддержку графики в реальном времени и, следовательно, ориентированы на обработку в двух, трех или четырех измерениях, обычно с длиной вектора от двух до шестнадцати слов, в зависимости от типа данных и архитектуры. Когда новые архитектуры SIMD необходимо отличать от старых, более новые архитектуры тогда считаются архитектурами «коротких векторов», поскольку более ранние SIMD и векторные суперкомпьютеры имели длину вектора от 64 до 64 000. Современный суперкомпьютер почти всегда представляет собой кластер компьютеров MIMD, каждый из которых реализует инструкции SIMD (коротких векторов).
Приложение, которое может использовать преимущества SIMD, — это приложение, в котором одно и то же значение добавляется (или вычитается) к большому количеству точек данных, что является обычной операцией во многих мультимедийных приложениях. Одним из примеров может служить изменение яркости изображения. Каждый пиксель изображения состоит из трех значений яркости красной (R), зеленой (G) и синей (B) частей цвета. Чтобы изменить яркость, значения R, G и B считываются из памяти, к ним добавляется (или вычитается) значение, и полученные значения записываются обратно в память. Аналогичным образом аудио DSP для управления громкостью одновременно умножают левый и правый каналы.
С процессором SIMD этот процесс имеет два усовершенствования. Во-первых, данные понимаются как находящиеся в блоках, и несколько значений могут быть загружены все одновременно. Вместо серии инструкций, говорящих «извлечь этот пиксель, теперь извлечь следующий пиксель», процессор SIMD будет иметь одну инструкцию, которая фактически говорит «извлечь n пикселей» (где n — число, которое меняется от дизайна к дизайну). По разным причинам это может занять гораздо меньше времени, чем извлечение каждого пикселя по отдельности, как в традиционной конструкции ЦП.
Другим преимуществом является то, что инструкция работает со всеми загруженными данными за одну операцию. Другими словами, если система SIMD работает, загружая восемь точек данных одновременно, то add
операция, применяемая к данным, будет происходить со всеми восемью значениями одновременно. Этот параллелизм отделен от параллелизма, обеспечиваемого суперскалярным процессором ; восемь значений обрабатываются параллельно даже на несуперскалярном процессоре, а суперскалярный процессор может выполнять несколько операций SIMD параллельно.
Для устранения проблем 1 и 5 векторное расширение RISC-V использует альтернативный подход: вместо того, чтобы выставлять программисту детали уровня подрегистра, набор инструкций абстрагирует их как несколько «векторных регистров», которые используют те же интерфейсы во всех ЦП с этим набором инструкций. Аппаратное обеспечение обрабатывает все проблемы выравнивания и «выемки» циклов. Машины с разными размерами векторов смогут выполнять один и тот же код. LLVM называет этот векторный тип «vscale». [ необходима цитата ]
Увеличение размера кода на порядок не является чем-то необычным по сравнению с эквивалентным скалярным или эквивалентным векторным кодом, а эффективность (выполняемая работа за одну инструкцию) на порядок или выше достижима с помощью векторных ISA. [6]
Масштабируемое векторное расширение ARM использует другой подход, известный в таксономии Флинна как «ассоциативная обработка», более известный сегодня как «предикативный» (маскированный) SIMD. Этот подход не такой компактный, как векторная обработка , но все равно намного лучше непредиктивного SIMD. Подробные сравнительные примеры приведены на странице векторной обработки .
Маломасштабные (64 или 128 бит) SIMD стали популярными на универсальных процессорах в начале 1990-х годов и продолжили свое развитие до 1997 года и позже с Motion Video Instructions (MVI) для Alpha. Инструкции SIMD можно найти, в той или иной степени, в большинстве процессоров, включая IBM AltiVec и SPE для PowerPC , HP PA - RISC Multimedia Acceleration eXtensions (MAX), Intel MMX и iwMMXt , SSE , SSE2 , SSE3 SSSE3 и SSE4.x , AMD 3DNow !, ARC ARC Video subsystem, SPARC VIS и VIS2, Sun MAJC , ARM Neon technology, MIPS MDMX (MaDMaX) и MIPS - 3D . IBM, Sony, Toshiba совместно разработали набор инструкций процессора Cell SPU, в значительной степени основанный на SIMD. Philips , теперь NXP , разработали несколько процессоров SIMD под названием Xetal . Xetal имеет 320 16-битных процессорных элементов, специально разработанных для задач зрения.
Инструкции Intel AVX-512 SIMD обрабатывают 512 бит данных одновременно.
Инструкции SIMD широко используются для обработки 3D-графики, хотя современные графические карты со встроенным SIMD в значительной степени взяли на себя эту задачу от центрального процессора. Некоторые системы также включают функции перестановки, которые переупаковывают элементы внутри векторов, что делает их особенно полезными для обработки и сжатия данных. Они также используются в криптографии. [7] [8] [9] Тенденция к вычислениям общего назначения на графических процессорах ( GPGPU ) может привести к более широкому использованию SIMD в будущем.
Внедрение систем SIMD в программное обеспечение персональных компьютеров поначалу было медленным из-за ряда проблем. Одна из них заключалась в том, что многие из ранних наборов инструкций SIMD имели тенденцию замедлять общую производительность системы из-за повторного использования существующих регистров с плавающей точкой. Другие системы, такие как MMX и 3DNow!, предлагали поддержку типов данных, которые не были интересны широкой аудитории, и имели дорогостоящие инструкции по переключению контекста для переключения между использованием регистров FPU и MMX . Компиляторы также часто не имели поддержки, что требовало от программистов прибегать к кодированию на языке ассемблера .
SIMD на x86 стартовал медленно. Введение 3DNow! от AMD и SSE от Intel несколько запутало ситуацию, но сегодня система, похоже, успокоилась (после того, как AMD приняла SSE), и новые компиляторы должны привести к большему количеству программного обеспечения с поддержкой SIMD. Intel и AMD теперь предоставляют оптимизированные математические библиотеки, которые используют инструкции SIMD, и начали появляться альтернативы с открытым исходным кодом, такие как libSIMD, SIMDx86 и SLEEF (см. также libm ). [10]
Apple Computer добились несколько большего успеха, хотя они вышли на рынок SIMD позже остальных. AltiVec предлагал богатую систему и мог программироваться с использованием все более сложных компиляторов от Motorola , IBM и GNU , поэтому программирование на языке ассемблера требовалось редко. Кроме того, многие из систем, которые могли бы выиграть от SIMD, поставлялись самой Apple, например iTunes и QuickTime . Однако в 2006 году компьютеры Apple перешли на процессоры Intel x86. API и инструменты разработки Apple ( XCode ) были изменены для поддержки SSE2 и SSE3 , а также AltiVec. Apple была доминирующим покупателем чипов PowerPC у IBM и Freescale Semiconductor . Несмотря на то, что Apple прекратила использовать процессоры PowerPC в своих продуктах, дальнейшее развитие AltiVec продолжается в нескольких конструкциях PowerPC и Power ISA от Freescale и IBM.
SIMD в регистре , или SWAR , представляет собой ряд методов и приемов, используемых для выполнения SIMD в регистрах общего назначения на оборудовании, которое не обеспечивает прямой поддержки инструкций SIMD. Это может быть использовано для эксплуатации параллелизма в определенных алгоритмах даже на оборудовании, которое не поддерживает SIMD напрямую.
Издатели наборов инструкций SIMD часто создают собственные расширения языка C/C++ со встроенными функциями или специальными типами данных (с перегрузкой операторов ), гарантирующими генерацию векторного кода. Intel, AltiVec и ARM NEON предоставляют расширения, широко используемые компиляторами, ориентированными на их процессоры. (Более сложные операции являются задачей библиотек векторной математики.)
Компилятор GNU C выводит расширения на новый уровень, абстрагируя их в универсальный интерфейс, который можно использовать на любой платформе, предоставляя способ определения типов данных SIMD. [11] Компилятор LLVM Clang также реализует эту функцию с аналогичным интерфейсом, определенным в IR. [12] Ящик Rust packed_simd
(и экспериментальный std::sims
) использует этот интерфейс, как и Swift 2.0+.
C++ имеет экспериментальный интерфейс std::experimental::simd
, который работает аналогично расширению GCC. Похоже, что libcxx LLVM реализует его. [ необходима цитата ] Для GCC и libstdc++ доступна библиотека-обертка, которая строится поверх расширения GCC. [13]
Microsoft добавила SIMD в .NET в RyuJIT. [14] Пакет System.Numerics.Vector
, доступный на NuGet, реализует типы данных SIMD. [15] Java также имеет новый предлагаемый API для инструкций SIMD, доступный в OpenJDK 17 в инкубаторном модуле. [16] Он также имеет безопасный механизм отката на неподдерживаемых ЦП к простым циклам.
Вместо предоставления типа данных SIMD, компиляторам также можно подсказать, чтобы они автоматически векторизовали некоторые циклы, потенциально принимая некоторые утверждения об отсутствии зависимости от данных. Это не так гибко, как прямая манипуляция переменными SIMD, но проще в использовании. OpenMP 4.0+ имеет #pragma omp simd
подсказку. [17] Этот интерфейс OpenMP заменил широкий набор нестандартных расширений, включая Cilk 's #pragma simd
, [18] GCC 's #pragma GCC ivdep
, и многие другие. [19]
Потребительское программное обеспечение, как правило, должно работать на ряде ЦП, охватывающих несколько поколений, что может ограничить возможности программиста использовать новые инструкции SIMD для улучшения вычислительной производительности программы. Решение состоит в том, чтобы включить несколько версий одного и того же кода, использующего либо старые, либо новые технологии SIMD, и выбрать ту, которая лучше всего подходит для ЦП пользователя во время выполнения ( динамическая диспетчеризация ). Существует два основных лагеря решений:
FMV, вручную закодированный на языке ассемблера, довольно часто используется в ряде библиотек, критически важных для производительности, таких как glibc и libjpeg-turbo. Intel C++ Compiler , GNU Compiler Collection начиная с GCC 6 и Clang начиная с clang 7 позволяют использовать упрощенный подход, при котором компилятор заботится о дублировании и выборе функций. GCC и clang требуют явных target_clones
меток в коде для «клонирования» функций, [20] в то время как ICC делает это автоматически (с помощью параметра командной строки /Qax
). Язык программирования Rust также поддерживает FMV. Настройка похожа на GCC и Clang в том, что код определяет, какие наборы инструкций компилировать, но клонирование выполняется вручную с помощью встраивания. [21]
Поскольку использование FMV требует модификации кода в GCC и Clang, поставщики чаще используют многоверсионность библиотек: этого проще добиться, поскольку нужно изменить только переключатели компилятора. Glibc поддерживает LMV, и эта функциональность принята поддерживаемым Intel проектом Clear Linux. [22]
В 2013 году Джон МакКатчан объявил, что он создал высокопроизводительный интерфейс для наборов инструкций SIMD для языка программирования Dart , впервые привнеся преимущества SIMD в веб-программы. Интерфейс состоит из двух типов: [23]
Экземпляры этих типов неизменяемы и в оптимизированном коде отображаются непосредственно в регистры SIMD. Операции, выраженные в Dart, обычно компилируются в одну инструкцию без каких-либо накладных расходов. Это похоже на встроенные функции C и C++. Тесты для умножения матриц 4×4 , преобразования трехмерных вершин и визуализации множества Мандельброта показывают почти 400% ускорение по сравнению со скалярным кодом, написанным в Dart.
Работа МакКатчана над Dart, теперь называемая SIMD.js, была принята ECMAScript , и Intel объявила на IDF 2013, что они реализуют спецификацию МакКатчана как для V8 , так и для SpiderMonkey . [24] Однако к 2017 году SIMD.js был исключен из стандартной очереди ECMAScript в пользу разработки аналогичного интерфейса в WebAssembly . [25] По состоянию на август 2020 года интерфейс WebAssembly оставался незавершённым, но его переносимая 128-битная функция SIMD уже нашла некоторое применение во многих движках.
Emscripten, компилятор Mozilla C/C++-to-JavaScript, с расширениями может обеспечить компиляцию программ C++, использующих встроенные функции SIMD или векторный код в стиле GCC, в API SIMD JavaScript, что приводит к эквивалентному ускорению по сравнению со скалярным кодом. [26] Он также поддерживает (и теперь предпочитает) предложение WebAssembly 128-бит SIMD. [27]
Как правило, оказывается сложным найти устойчивое коммерческое применение для процессоров, поддерживающих только SIMD.
Один из них, который имел определенный успех, — это GAPP , разработанный Lockheed Martin и выведенный в коммерческий сектор их ответвлением Teranex. Последние воплощения GAPP стали мощным инструментом в приложениях обработки видео в реальном времени , таких как преобразование между различными видеостандартами и частотами кадров ( NTSC в/из PAL , NTSC в/из форматов HDTV и т. д.), деинтерлейсинг , шумоподавление изображения , адаптивное сжатие видео и улучшение изображения.
Более распространенное применение SIMD можно найти в видеоиграх : почти каждая современная игровая консоль с 1998 года включает в себя процессор SIMD где-то в своей архитектуре. PlayStation 2 была необычна тем, что один из ее векторно-плавающих блоков мог функционировать как автономный DSP, выполняющий собственный поток инструкций, или как сопроцессор, управляемый обычными инструкциями ЦП. Приложения 3D-графики, как правило, хорошо поддаются обработке SIMD, поскольку они в значительной степени зависят от операций с 4-мерными векторами. Direct3D 9.0 от Microsoft теперь выбирает во время выполнения специфичные для процессора реализации собственных математических операций, включая использование инструкций с поддержкой SIMD.
Более поздний процессор, который использовал векторную обработку, — это процессор Cell , используемый в Playstation 3, который был разработан IBM совместно с Toshiba и Sony . Он использует ряд процессоров SIMD ( архитектура NUMA , каждый с независимым локальным хранилищем и управляемый универсальным ЦП) и ориентирован на огромные наборы данных, требуемые приложениями обработки 3D и видео. Он отличается от традиционных ISA тем, что изначально является SIMD без отдельных скалярных регистров.
Компания Ziilabs выпустила процессор типа SIMD для использования на мобильных устройствах, таких как медиаплееры и мобильные телефоны. [28]
Более крупные коммерческие процессоры SIMD доступны от ClearSpeed Technology, Ltd. и Stream Processors, Inc. CSX600 (2004) от ClearSpeed имеет 96 ядер, каждое с двумя блоками с плавающей точкой двойной точности, в то время как CSX700 (2008) имеет 192 ядра. Stream Processors возглавляет компьютерный архитектор Билл Далли . Их процессор Storm-1 (2007) содержит 80 ядер SIMD, управляемых центральным процессором MIPS.