Векторный процессор
В вычислениях или векторный процессор процессор массива — это центральный процессор (ЦП), который реализует набор команд , где его инструкции предназначены для эффективной и действенной работы с большими одномерными массивами данных, называемыми векторами . Это отличается от скалярных процессоров , чьи инструкции работают только с отдельными элементами данных, и в отличие от некоторых из тех же самых скалярных процессоров, имеющих дополнительные с одной командой, несколькими данными (SIMD) или SIMD в регистре арифметические единицы (SWAR). Векторные процессоры могут значительно повысить производительность при выполнении определенных рабочих нагрузок, особенно при численном моделировании и подобных задачах. Методы векторной обработки также используются в оборудовании игровых консолей и графических ускорителях .
Векторные машины появились в начале 1970-х годов и доминировали в разработке суперкомпьютеров с 1970-х по 1990-е годы, особенно в различных платформах Cray . Быстрое падение соотношения цены и производительности традиционных микропроцессоров привело к упадку векторных суперкомпьютеров в 1990-е годы.
История
[ редактировать ]Ранние исследования и разработки
[ редактировать ]Разработка векторной обработки началась в начале 1960-х годов в компании Westinghouse Electric Corporation в рамках их «Соломон» проекта . Целью Соломона было резко повысить математическую производительность за счет использования большого количества простых сопроцессоров под управлением одного главного центрального процессора (ЦП). ЦП подавал одну общую инструкцию всем арифметико-логическим устройствам (АЛУ), по одной на цикл, но с разными точками данных для работы каждого из них. Это позволило машине Соломона применить единый алгоритм к большому набору данных , подаваемому в виде массива. [ нужна ссылка ]
В 1962 году Westinghouse отменила проект, но его возобновил Университет Иллинойса в Урбане-Шампейне под названием ILLIAC IV . Их версия конструкции первоначально предусматривала машину с производительностью 1 GFLOPS и 256 ALU, но, когда она была наконец выпущена в 1972 году, она имела только 64 ALU и могла достигать производительности только от 100 до 150 MFLOPS. Тем не менее, он показал, что базовая концепция была верной, и при использовании в приложениях с интенсивным использованием данных, таких как вычислительная гидродинамика , ILLIAC оказался самой быстрой машиной в мире. Подход ILLIAC, заключающийся в использовании отдельных ALU для каждого элемента данных, не является общим для более поздних разработок и часто упоминается в отдельной категории — массово-параллельные вычисления. Примерно в это же время Флинн классифицировал этот тип обработки как раннюю форму одиночной инструкции и нескольких потоков (SIMT). [ нужна ссылка ]
Компания International Computers Limited стремилась избежать многих трудностей, связанных с концепцией ILLIAC, с помощью собственной конструкции процессора с распределенными массивами (DAP), классифицируя ILLIAC и DAP как процессоры с сотовыми массивами, которые потенциально предлагали существенные преимущества в производительности по сравнению с традиционными конструкциями векторных процессоров, такими как CDC STAR. -100 и Крей 1. [1]
Компьютер для работы с функциями
[ редактировать ]Компьютер для работы с функциями был представлен и разработан Карцевым в 1967 году. [2]
Суперкомпьютеры
[ редактировать ]Первыми векторными суперкомпьютерами являются Control Data Corporation STAR-100 и (ASC) компании Texas Instruments Advanced Scientific Computer , которые были представлены в 1974 и 1972 годах соответственно.
В базовом ASC (т. е. «одноконвейерном») ALU использовалась конвейерная архитектура, которая поддерживала как скалярные, так и векторные вычисления, при этом пиковая производительность достигала примерно 20 MFLOPS, что легко достигалось при обработке длинных векторов. Расширенные конфигурации ALU поддерживают «два канала» или «четыре канала» с соответствующим увеличением производительности в 2 или 4 раза. Пропускной способности памяти было достаточно для поддержки этих расширенных режимов.
В остальном STAR-100 был медленнее, чем собственные суперкомпьютеры CDC, такие как CDC 7600 , но при выполнении задач, связанных с данными, они могли справляться с ними, будучи намного меньшими и менее дорогими. Однако машине также потребовалось немало времени на декодирование векторных инструкций и подготовку к запуску процесса, поэтому ей требовались очень специфические наборы данных для работы, прежде чем она действительно что-либо ускорила.
Векторный метод был впервые полностью использован в 1976 году знаменитым Cray-1 . Вместо того, чтобы оставлять данные в памяти, как в STAR-100 и ASC, конструкция Cray имела восемь векторных регистров , каждый из которых содержал шестьдесят четыре 64-битных слова. Векторные инструкции применялись между регистрами, что намного быстрее, чем обращение к основной памяти. В то время как STAR-100 применял одну операцию к длинному вектору в памяти, а затем переходил к следующей операции, конструкция Cray загружала меньшую часть вектора в регистры, а затем применяла к этим данным как можно больше операций. , тем самым избегая многих гораздо более медленных операций доступа к памяти.
В конструкции Крэя для реализации векторных инструкций использовался конвейерный параллелизм, а не несколько ALU. Кроме того, в конструкции были совершенно отдельные конвейеры для разных инструкций, например, сложение/вычитание было реализовано на другом аппаратном обеспечении, чем умножение. Это позволило передать пакет векторных инструкций в каждый из субблоков ALU — метод, который они назвали векторной цепочкой . Cray-1 обычно имел производительность около 80 MFLOPS, но при подключении до трех цепей он мог достигать максимальной производительности 240 MFLOPS и в среднем около 150 — намного быстрее, чем любая машина того времени.
Последовали и другие примеры. Корпорация Control Data попыталась снова выйти на рынок high-end со своей машиной ETA-10 , но она продавалась плохо, и они восприняли это как возможность полностью покинуть область суперкомпьютеров. В начале и середине 1980-х годов японские компании ( Fujitsu , Hitachi и Nippon Electric Corporation (NEC) представили векторные машины на основе регистров, аналогичные Cray-1, обычно немного быстрее и намного меньше. Орегона на базе Системы с плавающей запятой (FPS) . построили дополнительные массивы процессоров для миникомпьютеров , а затем построили свои собственные минисуперкомпьютеры .
На протяжении всего этого времени компания Cray продолжала оставаться лидером по производительности, постоянно побеждая конкурентов с помощью серии машин, результатом которой стали Cray-2 , Cray X-MP и Cray Y-MP . С тех пор рынок суперкомпьютеров в большей степени сосредоточился на массовой параллельной обработке, а не на более совершенных реализациях векторных процессоров. Однако, осознавая преимущества векторной обработки, IBM разработала виртуальную векторную архитектуру для использования в суперкомпьютерах, объединяющих несколько скалярных процессоров в качестве векторного процессора.
Хотя векторные суперкомпьютеры, подобные Cray-1, в наши дни менее популярны, компания NEC продолжает производить компьютеры этого типа и по сей день, выпустив SX серию компьютеров . Совсем недавно в SX-Aurora TSUBASA процессор и 24 или 48 гигабайт памяти размещались на модуле HBM 2 внутри карты, которая физически напоминает графический сопроцессор, но вместо того, чтобы служить сопроцессором, она является основным компьютером с ПК-совместимый компьютер, к которому он подключен, выполняет вспомогательные функции.
графический процессор
[ редактировать ]Современные графические процессоры ( GPU ) включают в себя массив шейдерных конвейеров , которые могут управляться вычислительными ядрами и могут считаться векторными процессорами (с использованием аналогичной стратегии для сокрытия задержек памяти). Как показано в статье Флинна 1972 года, ключевым отличительным фактором графических процессоров на базе SIMT является то, что они имеют один декодер-транслятор инструкций, но ядра, получающие и выполняющие одну и ту же инструкцию, в остальном достаточно нормальны: свои собственные ALU, свои собственные файлы регистров, свои собственные блоки загрузки/сохранения и собственные независимые кэши данных L1. Таким образом, хотя все ядра одновременно выполняют одну и ту же инструкцию синхронно друг с другом, они делают это с совершенно разными данными из совершенно разных ячеек памяти. Это значительно сложнее и сложнее, чем «Packed SIMD» , который строго ограничен выполнением только параллельных конвейерных арифметических операций. Хотя точные внутренние детали современных коммерческих графических процессоров являются секретом компании, MIAOW [3] команде удалось собрать воедино неофициальную информацию, достаточную для реализации подмножества архитектуры AMDGPU. [4]
Последние разработки
[ редактировать ]Некоторые современные архитектуры ЦП разрабатываются как векторные процессоры. Векторное расширение RISC -V следует тем же принципам, что и ранние векторные процессоры, и реализуется в коммерческих продуктах, таких как Andes Technology AX45MPV. [5] Также с открытым исходным кодом разрабатывается несколько архитектур векторных процессоров , включая ForwardCom и Libre-SOC .
Сравнение с современной архитектурой
[ редактировать ]По состоянию на 2016 год [update] большинство обычных процессоров реализуют архитектуры, в которых используются инструкции SIMD фиксированной длины. На первый взгляд их можно рассматривать как форму векторной обработки, поскольку они работают с несколькими наборами данных (векторизованных, явной длины) и заимствуют функции векторных процессоров. Однако по определению добавление SIMD само по себе не может квалифицировать процессор как настоящий векторный процессор , поскольку SIMD имеет фиксированную длину , а векторы имеют переменную длину . Разница проиллюстрирована ниже на примерах, показывающих и сравнивающих три категории: Pure SIMD, Predicated SIMD и Pure Vector Processing. [ нужна ссылка ]
- Чистый (фиксированный) SIMD — также известный как «Упакованный SIMD», [6] SIMD в регистре (SWAR) и конвейерный процессор в таксономии Флинна. Общие примеры использования SIMD с функциями, вдохновленными векторными процессорами, включают: инструкции Intel x86 MMX , SSE и AVX , AMD 3DNow! расширения, ARM NEON от Sparc , расширение VIS , PowerPC от AltiVec от MIPS и MSA . В 2000 году IBM , Toshiba и Sony совместно создали процессор Cell , который также является SIMD.
- Предикатная SIMD — также известная как ассоциативная обработка . Двумя примечательными примерами, которые имеют предикацию для каждого элемента (на основе полос), являются ARM SVE2 и AVX-512.
- Чистые векторы , классифицированные в таксономии Дункана , включают оригинальные Cray-1 , Convex C-Series , NEC SX и RISC-V RVV . был основан на памяти, Несмотря на то, что CDC STAR-100 он также был векторным процессором.
Другие конструкции ЦП включают несколько множественных инструкций для векторной обработки нескольких (векторизованных) наборов данных, обычно известных как MIMD (множественные инструкции, множественные данные) и реализуемых с помощью VLIW (очень длинное командное слово) и EPIC (явно параллельные вычисления инструкций). Векторный процессор Fujitsu FR-V VLIW сочетает в себе обе технологии.
Разница между SIMD и векторными процессорами
[ редактировать ]Наборы команд SIMD лишены важных функций по сравнению с наборами векторных инструкций. Наиболее важным из них является то, что векторные процессоры по определению и конструкции всегда имели переменную длину с момента их создания.
В то время как чистый (фиксированной ширины, без предикации) SIMD часто ошибочно называют «векторным» (поскольку SIMD обрабатывает данные, которые оказываются векторами), посредством тщательного анализа и сравнения исторических и современных ISA можно заметить, что фактические векторные ISA имеют следующие функции, которых нет у SIMD ISA: [ нужна ссылка ]
- способ установки длины вектора, например
vsetvl
инструкция в RISCV RVV, [7] илиlvl
инструкция в NEC SX, [8] без ограничения длины степенью двойки или кратностью фиксированной ширины данных. - Итерация и сокращение элементов внутри векторов.
Предикатный SIMD (часть таксономии Флинна ), который представляет собой комплексные маски предикатов на уровне отдельных элементов для каждой векторной инструкции, которые теперь доступны в ARM SVE2. [9] А AVX-512 можно назвать практически векторным процессором. [ как? ] Предикативный SIMD использует SIMD ALU фиксированной ширины, но позволяет локально управляемую (предикативную) активацию модулей для обеспечения появления векторов переменной длины. Приведенные ниже примеры помогают объяснить эти категориальные различия.
SIMD, поскольку он использует пакетную обработку фиксированной ширины, по своей конструкции не может справиться с итерациями и сокращениями. Это дополнительно иллюстрируется примерами ниже.
Кроме того, векторные процессоры могут быть более ресурсоэффективными за счет использования более медленного оборудования и экономии энергии, но при этом обеспечивать пропускную способность и меньшую задержку, чем SIMD, за счет векторной цепочки . [10] [11]
Рассмотрим как SIMD-процессор, так и векторный процессор, работающий с четырьмя 64-битными элементами и выполняющий последовательности ЗАГРУЗКА, СЛОЖЕНИЕ, УМНОЖЕНИЕ и СОХРАНЕНИЕ. Если ширина SIMD равна 4, то процессор SIMD должен полностью ЗАГРУЗИТЬ четыре элемента, прежде чем он сможет перейти к ADD, должен завершить все операции ADD, прежде чем он сможет перейти к MULTIPLY, и аналогичным образом должен завершить все MULTIPLY, прежде чем он сможет запустите МАГАЗИНЫ. Это по определению и замыслу. [12]
Необходимость одновременного выполнения 4-битных 64-битных операций ЗАГРУЗКИ и 64-битных операций СОХРАНЕНИЯ требует очень больших аппаратных затрат (256-битные пути данных к памяти). Также имеется 4 64-битных ALU, особенно MULTIPLY. Чтобы избежать таких высоких затрат, SIMD-процессор должен иметь 64-битную загрузку 1 ширины, 64-битное хранилище STORE 1 ширины и только 64-битные ALU шириной 2 ширины. Как показано на диаграмме, которая предполагает модель выполнения с несколькими задачами , последствия заключаются в том, что выполнение операций теперь занимает больше времени. Если многовыпуск невозможен, то операции занимают еще больше времени, поскольку LD может не быть выдан (запущен) одновременно с первыми ADD и так далее. Если есть только 4-битные 64-битные SIMD ALU, время завершения еще хуже: только когда все четыре LOAD завершены, могут начаться операции SIMD, и только когда все операции ALU завершены, могут начаться STORE.
Векторный процессор, напротив, даже если он однозадачный и не использует SIMD ALU, имеет только 1-битную 64-битную ЗАГРУЗКУ, 1-битную 64-битную ЗАПИСЬ (и, как в Cray-1 , способность запустить MULTIPLY одновременно с ADD), может выполнить четыре операции быстрее, чем процессор SIMD с LOAD 1, STORE 1 и SIMD 2. Более эффективное использование ресурсов благодаря объединению векторов в цепочку является ключевым преимуществом и отличием от SIMD. SIMD по замыслу и определению не может выполнять цепочку, за исключением всей группы результатов. [13]
Описание
[ редактировать ]В общих чертах, процессоры могут манипулировать одним или двумя фрагментами данных одновременно. Например, у большинства процессоров есть инструкция, которая по сути говорит: «Добавьте A к B и поместите результат в C». Данные для A, B и C могут быть — по крайней мере теоретически — закодированы непосредственно в инструкции. Однако в эффективной реализации все редко бывает так просто. Данные редко отправляются в необработанном виде, вместо этого на них «указывают» путем передачи адреса в ячейку памяти, в которой хранятся данные. Декодирование этого адреса и получение данных из памяти занимает некоторое время, в течение которого процессор традиционно простаивает, ожидая появления запрошенных данных. По мере увеличения скорости процессора эта задержка памяти исторически стала серьезным препятствием для производительности; см . Стена памяти .
Чтобы сократить время, затрачиваемое на эти шаги, большинство современных процессоров используют метод, известный как конвейерная обработка инструкций , при котором инструкции по очереди проходят через несколько подблоков. Первый подблок считывает адрес и декодирует его, следующий «выбирает» значения по этим адресам, а следующий выполняет сами математические вычисления. При конвейерной обработке «хитрость» заключается в том, чтобы начать декодирование следующей инструкции еще до того, как первая покинет ЦП, подобно сборочной линии , поэтому декодер адреса используется постоянно. Для выполнения любой конкретной инструкции требуется одинаковое количество времени, время, известное как задержка , но ЦП может обрабатывать весь пакет операций перекрывающимся образом гораздо быстрее и эффективнее, чем если бы он делал это по одной.
Векторные процессоры развивают эту концепцию на шаг дальше. Вместо конвейерной передачи только инструкций они также конвейеризируют сами данные. Процессору подаются инструкции, в которых говорится не просто сложить А с Б, но и сложить все числа «отсюда сюда» ко всем числам «оттуда туда». инструкции просто подразумевается, Вместо того, чтобы постоянно декодировать инструкции и затем извлекать данные, необходимые для их выполнения, процессор считывает одну инструкцию из памяти, и в определении самой что инструкция снова будет работать с другим элементом данных. по адресу, который на один шаг больше предыдущего. Это позволяет существенно сэкономить время декодирования.
Чтобы проиллюстрировать, какую разницу это может иметь, рассмотрим простую задачу сложения двух групп по 10 чисел. На обычном языке программирования можно было бы написать «цикл», который поочередно собирал каждую из пар чисел, а затем складывал их. Для процессора это будет выглядеть примерно так:
; Hypothetical RISC machine
; assume a, b, and c are memory locations in their respective registers
; add 10 numbers in a to 10 numbers in b, store results in c
move $10, count ; count := 10
loop:
load r1, a
load r2, b
add r3, r1, r2 ; r3 := r1 + r2
store r3, c
add a, a, $4 ; move on
add b, b, $4
add c, c, $4
dec count ; decrement
jnez count, loop ; loop back if count is not yet 0
ret
Но для векторного процессора эта задача выглядит совершенно иначе:
; assume we have vector registers v1-v3
; with size equal or larger than 10
move $10, count ; count = 10
vload v1, a, count
vload v2, b, count
vadd v3, v1, v2
vstore v3, c, count
ret
Обратите внимание на полное отсутствие циклов в инструкциях, поскольку именно аппаратное обеспечение выполнило 10 последовательных операций: фактически счетчик циклов явно рассчитывается для каждой инструкции .
Векторные ISA в стиле Cray идут еще дальше и предоставляют глобальный регистр «счета», называемый длиной вектора (VL):
; again assume we have vector registers v1-v3
; with size larger than or equal to 10
setvli $10 # Set vector length VL=10
vload v1, a # 10 loads from a
vload v2, b # 10 loads from b
vadd v3, v1, v2 # 10 adds
vstore v3, c # 10 stores into c
ret
Этот подход дает несколько преимуществ экономии. [14]
- необходимы только три трансляции адресов. В зависимости от архитектуры это само по себе может привести к значительной экономии.
- Еще одна экономия — выборка и декодирование самой инструкции, которую нужно сделать только один раз вместо десяти.
- Сам код также стал меньше, что может привести к более эффективному использованию памяти, уменьшению размера кэша инструкций L1, снижению энергопотребления.
- При уменьшении размера программы прогнозирование ветвей становится проще.
- Поскольку длина (эквивалентная ширине SIMD) не жестко запрограммирована в инструкции, кодирование не только становится более компактным, но и «ориентированным на будущее» и позволяет даже конструкциям встроенных процессоров рассматривать возможность использования векторов исключительно для получения всех других преимуществ. , а не стремиться к высокой производительности.
Кроме того, в более современных векторных процессорах ISA появилась функция «Fail on First» или «Fault First» (см. ниже), что дает еще больше преимуществ.
Более того, высокопроизводительный векторный процессор может иметь несколько функциональных блоков, параллельно добавляющих эти числа. Проверка зависимостей между этими числами не требуется, поскольку векторная инструкция определяет несколько независимых операций. Это упрощает необходимую логику управления и может еще больше повысить производительность за счет предотвращения зависаний. Таким образом, математические операции в целом выполнялись гораздо быстрее, причем ограничивающим фактором было время, необходимое для извлечения данных из памяти.
Не все проблемы можно решить с помощью такого решения. Включение этих типов инструкций обязательно усложняет работу ядра ЦП. Эта сложность обычно приводит к тому, что другие инструкции выполняются медленнее, т. е. всякий раз, когда не складывается много чисел подряд. Более сложные инструкции также усложняют декодеры, что может замедлить декодирование более распространенных инструкций, таких как обычное сложение. ( Это можно несколько смягчить, сохранив все принципы ISA в RISC : RVV добавляет только около 190 векторных инструкций даже с расширенными функциями. [15] )
Векторные процессоры традиционно разрабатывались для наилучшей работы только при обработке больших объемов данных. По этой причине процессоры такого типа встречались в основном в суперкомпьютерах , так как сами суперкомпьютеры, как правило, находились в таких местах, как центры прогнозирования погоды и физические лаборатории, где «обрабатываются» огромные объемы данных. Однако, как показано выше и продемонстрировано RISC-V RVV, эффективность векторных ISA дает и другие преимущества, которые привлекательны даже для встраиваемых систем.
Векторные инструкции
[ редактировать ]В приведенном выше примере векторного псевдокода предполагается, что векторный компьютер может обрабатывать более десяти чисел за один пакет. При большем количестве чисел в векторном регистре компьютеру становится невозможно иметь такой большой регистр. В результате векторный процессор либо получает возможность самостоятельно выполнять циклы, либо предоставляет программисту своего рода регистр векторного управления (состояния), обычно известный как длина вектора.
Самоповторяющиеся инструкции встречаются в ранних векторных компьютерах, таких как STAR-100, где вышеуказанное действие описывалось одной командой (что-то вроде vadd c, a, b, $10
). Они также встречаются в архитектуре x86 как REP
префикс. Однако таким образом можно эффективно выполнять аппаратные средства только очень простых вычислений без значительного увеличения затрат. Поскольку в архитектуре STAR-100 все операнды должны находиться в памяти, задержка, вызванная доступом, также стала огромной.
Однако интересно, что Broadcom включила пространство во все векторные операции Videocore IV ISA. REP
поле, но в отличие от STAR-100, который использует память для своих повторов, повторы Videocore IV выполняются во всех операциях, включая арифметические векторные операции. Длина повтора может быть небольшим диапазоном, равным двум , или может быть получена из одного из скалярных регистров. [16]
Cray -1 представил идею использования регистров процессора для пакетного хранения векторных данных. Длины пакетов (длина вектора, VL) могут быть установлены динамически с помощью специальной инструкции, при этом значение по сравнению с Videocore IV (и, что особенно важно, как будет показано ниже, также с SIMD) заключается в том, что длина повтора не обязательно должна быть частью кодировка инструкции. Таким образом, в каждой партии можно выполнить значительно больше работы; кодирование инструкций также намного более элегантно и компактно. Единственным недостатком является то, что для того, чтобы в полной мере воспользоваться преимуществами дополнительной мощности пакетной обработки, необходимо также увеличить нагрузку на память и скорость хранения. Иногда это утверждают [ кем? ] Это является недостатком векторных процессоров в стиле Cray: на самом деле это часть достижения высокой производительности, как это видно на графических процессорах , которые сталкиваются с точно такой же проблемой.
Современные компьютеры SIMD утверждают, что они улучшили раннюю версию Cray за счет прямого использования нескольких ALU для более высокой степени параллелизма по сравнению с использованием только обычного скалярного конвейера. Современные векторные процессоры (такие как SX-Aurora TSUBASA ) сочетают в себе оба способа, выдавая несколько данных на несколько внутренних конвейерных SIMD ALU, причем количество выдаваемых данных динамически выбирается векторной программой во время выполнения. Маски можно использовать для выборочной загрузки и хранения данных в ячейках памяти, а также использовать те же маски для выборочного отключения обрабатывающего элемента SIMD ALU. Некоторые процессоры с SIMD ( AVX-512 , ARM SVE2 ) способны выполнять такого рода выборочную, поэлементную ( «предикатную» ) обработку, и именно они в некоторой степени заслуживают номенклатуры «векторный процессор» или, по крайней мере, заслуживают требования способность к «векторной обработке». SIMD-процессоры без поэлементного определения ( MMX , SSE , AltiVec ) категорически нет.
Современные графические процессоры, которые имеют множество небольших вычислительных блоков, каждый из которых имеет свои собственные независимые SIMD ALU, используют одноинструкционную многопоточность (SIMT). Модули SIMT запускаются из общего модуля команд с синхронизацией широковещательной передачи. «Векторные регистры» очень широки, а конвейеры имеют тенденцию быть длинными. «Поточная» часть SIMT включает в себя способ обработки данных независимо на каждом из вычислительных блоков.
Кроме того, графические процессоры, такие как Broadcom Videocore IV, и другие внешние векторные процессоры, такие как NEC SX-Aurora TSUBASA, могут использовать меньше векторных единиц, чем предполагает ширина: вместо 64 единиц для регистра шириной 64 числа аппаратное обеспечение может вместо этого использовать выполните конвейерный цикл из 16 единиц для гибридного подхода. Broadcom Videocore IV также способен на этот гибридный подход: номинально заявляя, что его SIMD QPU Engine поддерживает в своих инструкциях операции с массивом FP длиной 16, на самом деле он выполняет их по 4 за раз, как (еще одна) форма «потоков». [17]
Пример векторной инструкции
[ редактировать ]Этот пример начинается с алгоритма («IAXPY»), сначала покажите его в виде скалярных инструкций, затем SIMD, затем предикативных SIMD и, наконец, векторных инструкций. Это постепенно помогает проиллюстрировать разницу между традиционным векторным процессором и современным SIMD. Пример начинается с 32-битного целочисленного варианта функции «DAXPY» на языке C :
void iaxpy(size_t n, int a, const int x[], int y[]) {
for (size_t i = 0; i < n; i++)
y[i] = a * x[i] + y[i];
}
На каждой итерации к каждому элементу y добавляется элемент x, умноженный на a. Программа представлена в скалярно-линейной форме для удобства чтения.
Скалярный ассемблер
[ редактировать ]Скалярная версия этого алгоритма будет загружать по одному из x и y, обрабатывать одно вычисление, сохранять один результат и выполнять цикл:
loop:
load32 r1, x ; load one 32bit data
load32 r2, y
mul32 r1, a, r1 ; r1 := r1 * a
add32 r3, r1, r2 ; r3 := r1 + r2
store32 r3, y
addl x, x, $4 ; x := x + 4
addl y, y, $4
subl n, n, $1 ; n := n - 1
jgz n, loop ; loop back if n > 0
out:
ret
Код, подобный STAR, остается кратким, но поскольку векторизация STAR-100 изначально была основана на доступе к памяти, для обработки информации теперь требуется дополнительный слот памяти. Также требуется двукратное увеличение задержки из-за дополнительных требований к доступу к памяти.
; Assume tmp is pre-allocated
vmul tmp, a, x, n ; tmp[i] = a * x[i]
vadd y, y, tmp, n ; y[i] = y[i] + tmp[i]
ret
Чистый (непредсказанный, упакованный) SIMD
[ редактировать ]Современная упакованная архитектура SIMD, известная под многими именами (перечисленными в таксономии Флинна ), может выполнять большую часть операций в пакетном режиме. Код во многом похож на скалярную версию. Предполагается, что и x, и y здесь правильно выровнены (только начинаются с числа, кратного 16) и что n кратно 4, поскольку в противном случае для расчета маски или запуска скалярной версии потребуется некоторый код настройки. Для простоты также можно предположить, что инструкции SIMD имеют возможность автоматически повторять скалярные операнды, как это может делать ARM NEON. [18] Если это не так, необходимо использовать «splat» (широковещательную рассылку) для копирования скалярного аргумента в регистр SIMD:
splatx4 v4, a ; v4 = a,a,a,a
Затраченное время будет в основном таким же, как и при векторной реализации y = mx + c
описано выше.
vloop:
load32x4 v1, x
load32x4 v2, y
mul32x4 v1, a, v1 ; v1 := v1 * a
add32x4 v3, v1, v2 ; v3 := v1 + v2
store32x4 v3, y
addl x, x, $16 ; x := x + 16
addl y, y, $16
subl n, n, $4 ; n := n - 4
jgz n, vloop ; go back if n > 0
out:
ret
Обратите внимание, что оба указателя x и y увеличиваются на 16, потому что именно столько (в байтах) имеют четыре 32-битных целых числа. Было принято решение, что алгоритм будет работать только с 4-х SIMD, поэтому константа жестко запрограммирована в программе.
К несчастью для SIMD, подсказка заключалась в приведенном выше предположении, что «n кратно 4», а также в «выровненном доступе», который, очевидно, является ограниченным вариантом использования для специалистов.
Реально, для циклов общего назначения, таких как в переносимых библиотеках, где n не может быть ограничено таким образом, накладные расходы на настройку и очистку SIMD для обработки некратных ширине SIMD могут значительно превысить количество команд внутри. сама петля. Если предположить, что в худшем случае оборудование не может выполнить несогласованный доступ к памяти SIMD, реальный алгоритм будет:
- сначала необходимо иметь подготовительный раздел, который работает с начальными невыровненными данными, вплоть до первой точки, когда операции с выравниванием по памяти SIMD могут взять верх. это будет либо включать (более медленные) скалярные операции, либо упакованные SIMD-операции меньшего размера. Каждая копия реализует полный внутренний цикл алгоритма.
- выполнить выровненный цикл SIMD с максимальной шириной SIMD до последних нескольких элементов (оставшихся, которые не соответствуют фиксированной ширине SIMD)
- есть этап очистки, который, как и подготовительный этап, такой же большой и сложный.
SIMD восьми ширины требует повторения алгоритма внутреннего цикла сначала с элементами SIMD четырех ширины, затем SIMD двух ширины, затем одного (скалярного), с тестом и ветвью между каждым из них, чтобы охватить первый и последний оставшийся SIMD. элементы (0 <= n <= 7).
Это более чем в три раза увеличивает размер кода, а в крайних случаях это приводит к увеличению количества инструкций на порядок ! Это можно легко продемонстрировать, скомпилировав пример iaxpy для AVX-512 , используя параметры "-O3 -march=knl"
в gcc .
Со временем, по мере того, как ISA развивается и продолжает повышать производительность, это приводит к тому, что ISA Architects добавляют SIMD с 2-мя панелями, затем с 4-мя SIMD, затем с 8-ми и выше. Таким образом, можно понять, почему AVX-512 существует в x86.
Без предсказывания, чем шире ширина SIMD, тем хуже становятся проблемы, что приводит к массовому увеличению количества кодов операций, снижению производительности, дополнительному энергопотреблению и ненужной сложности программного обеспечения. [19]
С другой стороны, векторные процессоры предназначены для выполнения вычислений переменной длины для произвольного числа n и, следовательно, требуют очень малой настройки и никакой очистки. Даже по сравнению с теми SIMD ISA, у которых есть маски (но нет setvl
инструкции), векторные процессоры создают гораздо более компактный код, поскольку им не нужно выполнять явный расчет маски для покрытия нескольких последних элементов (показано ниже).
Предикатный SIMD
[ редактировать ]Предполагая гипотетический предикатный (с поддержкой маски) SIMD ISA и снова предполагая, что инструкции SIMD могут обрабатывать невыровненные данные, цикл инструкций будет выглядеть следующим образом:
vloop:
# prepare mask. few ISAs have min though
min t0, n, $4 ; t0 = min(n, 4)
shift m, $1, t0 ; m = 1<<t0
sub m, m, $1 ; m = (1<<t0)-1
# now do the operation, masked by m bits
load32x4 v1, x, m
load32x4 v2, y, m
mul32x4 v1, a, v1, m ; v1 := v1 * a
add32x4 v3, v1, v2, m ; v3 := v1 + v2
store32x4 v3, y, m
# update x, y and n for next loop
addl x, t0*4 ; x := x + t0*4
addl y, t0*4
subl n, n, t0 ; n := n - t0
# loop?
jgz n, vloop ; go back if n > 0
out:
ret
Здесь видно, что код намного чище, но немного сложнее: по крайней мере, здесь нет настройки или очистки: на последней итерации цикла маска предиката будет установлена в значение 0b0000, 0b0001, 0b0011, 0b0111 или 0b1111, что приводит к выполнению от 0 до 4 операций с элементом SIMD соответственно. Еще одно потенциальное осложнение: некоторые RISC ISA не имеют инструкции «min», вместо этого необходимо использовать ветвление или скалярное предикатное сравнение.
Понятно, что предикатный SIMD, по крайней мере, заслуживает термина «совместимый с векторами», поскольку он может справляться с векторами переменной длины за счет использования масок предикатов. Однако последним шагом на пути к «истинной» векторной ISA является полное отсутствие в ISA каких-либо свидетельств ширины SIMD, оставляя это полностью на усмотрение аппаратного обеспечения.
Чистый (истинный) вектор ISA
[ редактировать ]Для векторных ISA в стиле Cray, таких как RVV, используется команда setvl (установка длины вектора). Аппаратное обеспечение сначала определяет, сколько значений данных оно может обработать в одном «векторе»: это могут быть либо реальные регистры, либо внутренний цикл (гибридный подход, упомянутый выше). Это максимальное количество (количество аппаратных «полос») называется «MVL» (максимальная длина вектора). Обратите внимание, что, как видно из SX-Aurora и Videocore IV, MVL может быть реальным количеством аппаратных линий или виртуальным . (Примечание. Как упоминалось в руководстве по ARM SVE2, программисты не должны совершать ошибку, предполагая фиксированную ширину вектора: следовательно, MVL не является величиной, которую необходимо знать программисту. Это может немного сбивать с толку после многих лет мышления SIMD). [ тон ]
При вызове setvl с указанием количества элементов данных, подлежащих обработке, «setvl» разрешается (по существу требуется) ограничить это значение максимальной длиной вектора (MVL) и, таким образом, возвращает фактическое число, которое может быть обработано оборудованием в последующем векторе. инструкции и устанавливает во внутреннем специальном регистре «VL» ту же самую сумму. В своих руководствах по SVE2 ARM называет этот метод программированием без учета длины вектора. [20]
Ниже представлен векторный ассемблер в стиле Cray для того же цикла в стиле SIMD, что и выше. Обратите внимание, что t0 (который, содержащий удобную копию VL, может варьироваться) используется вместо жестко запрограммированных констант:
vloop:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vld32 v1, y # load vector y
vmadd32 v1, v0, a # v1 += v0 * a
vst32 v1, y # store Y
add y, t0*4 # advance y by VL*4
add x, t0*4 # advance x by VL*4
sub n, t0 # n -= VL (t0)
bnez n, vloop # repeat if n != 0
По сути, это не сильно отличается от версии SIMD (обрабатывает 4 элемента данных за цикл) или от исходной версии Scalar (обрабатывает только один). n по-прежнему содержит количество элементов данных, которые осталось обработать, но t0 содержит копию VL — число, которое будет обрабатываться на каждой итерации. t0 вычитается из n после каждой итерации, и если n равно нулю, то все элементы обработаны.
При сравнении с вариантом сборки Predicated SIMD следует отметить ряд моментов:
- The
setvl
инструкция включает в себяmin
инструкция - Там, где вариант SIMD жестко запрограммировал как ширину (4) при создании маски , так и ширину SIMD (load32x4 и т. д.), векторные эквиваленты ISA не имеют такого ограничения. Это делает векторные программы портативными, независимыми от поставщиков и перспективными.
- Установка VL эффективно создает скрытую маску предиката , которая автоматически применяется к векторам.
- Если при использовании предикатного SIMD длина маски ограничена той, которая может храниться в скалярном (или специальной маске) регистре, то векторные регистры маски ISA не имеют такого ограничения. Векторы Cray-I могли состоять чуть более 1000 элементов (в 1977 году).
Таким образом, очень ясно видно, как векторные ISA уменьшают количество инструкций.
Также обратите внимание, что, как и в варианте SIMD с предикатом, указатели на x и y увеличиваются на t0 раз в четыре, потому что они оба указывают на 32-битные данные, но n уменьшается на прямой t0. По сравнению с ассемблером SIMD фиксированного размера очевидная разница очень невелика: x и y увеличиваются на жестко запрограммированную константу 16, n уменьшается на жестко запрограммированную 4, поэтому изначально трудно оценить значение. Разница заключается в том, что векторное оборудование может выполнять одновременно 4 операции, или 64, или 10 000, это будет один и тот же ассемблер векторов для всех них , и при этом не будет кода очистки SIMD . Даже по сравнению с SIMD с поддержкой предикатов, он все еще более компактен, понятен, элегантен и использует меньше ресурсов.
Это не только гораздо более компактная программа (экономия размера кэша L1), но, как упоминалось ранее, векторная версия может выполнять гораздо большую обработку данных для ALU, что опять же экономит электроэнергию, поскольку инструкции декодирования и выполнения могут простаивать.
Кроме того, количество элементов, входящих в функцию, может начинаться с нуля. Это устанавливает длину вектора равной нулю, что фактически отключает все векторные инструкции, превращая их в пустые во время выполнения. Таким образом, в отличие от непредикатного SIMD, даже когда нет элементов для обработки, ненужного кода очистки все равно нет.
Пример векторного сокращения
[ редактировать ]Этот пример начинается с алгоритма, который включает сокращение. Как и в предыдущем примере, сначала это будет показано в скалярных инструкциях, затем в SIMD и, наконец, в векторных инструкциях, начиная с c :
void (size_t n, int a, const int x[]) {
int y = 0;
for (size_t i = 0; i < n; i++)
y += x[i];
return y;
}
Здесь аккумулятор (y) используется для суммирования всех значений в массиве x.
Скалярный ассемблер
[ редактировать ]Скалярная версия этого алгоритма будет загружать каждый из x, добавлять его к y и выполнять цикл:
set y, 0 ; y initialised to zero
loop:
load32 r1, x ; load one 32bit data
add32 y, y, r1 ; y := y + r1
addl x, x, $4 ; x := x + 4
subl n, n, $1 ; n := n - 1
jgz n, loop ; loop back if n > 0
out:
ret y ; returns result, y
Это очень просто. «y» начинается с нуля, 32-битные целые числа по одному загружаются в r1, добавляются к y, а адрес массива «x» перемещается к следующему элементу массива.
Снижение SIMD
[ редактировать ]Здесь начинаются проблемы. SIMD по своей конструкции не способен выполнять арифметические операции «межэлементно». Элемент 0 одного регистра SIMD может быть добавлен к элементу 0 другого регистра, но элемент 0 не может быть добавлен ни к чему другому, кроме другого элемента 0. Это накладывает некоторые серьезные ограничения на потенциальные реализации. Для простоты можно предположить, что n равно ровно 8:
addl r3, x, $16 ; for 2nd 4 of x
load32x4 v1, x ; first 4 of x
load32x4 v2, r3 ; 2nd 4 of x
add32x4 v1, v2, v1 ; add 2 groups
На данный момент было выполнено четыре добавления:
x[0]+x[4]
- Первое SIMD ADD: элемент 0 первой группы добавлен к элементу 0 второй группы.x[1]+x[5]
- Второе SIMD ADD: элемент 1 первой группы добавлен к элементу 1 второй группы.x[2]+x[6]
- Третье SIMD ADD: элемент 2 первой группы добавлен к элементу 2 второй группы.x[3]+x[7]
- Четвертое SIMD ADD: элемент 3 первой группы добавлен к элементу 2 второй группы.
но поскольку SIMD с 4 шириной по своей конструкции не может добавлять x[0]+x[1]
например, дела идут быстро вниз, как и в общем случае использования SIMD для циклов IAXPY общего назначения. Чтобы суммировать четыре частичных результата, можно использовать SIMD двухширинного размера с последующим одиночным скалярным сложением, чтобы окончательно получить ответ, но часто данные должны быть переданы из выделенных регистров SIMD, прежде чем можно будет выполнить последнее скалярное вычисление. .
Даже при общем цикле (n не фиксировано) единственный способ использовать SIMD шириной 4 — это предположить четыре отдельных «потока», каждый из которых смещен на четыре элемента. Наконец, необходимо суммировать четыре частичных результата. Другие методы включают перетасовку: В Интернете можно найти примеры для AVX-512, как выполнить «Горизонтальную сумму». [21] [22]
Помимо размера и сложности программы, если задействованы вычисления с плавающей запятой, возникает дополнительная потенциальная проблема: тот факт, что значения не суммируются в строгом порядке (четыре частичных результата), может привести к ошибкам округления.
Векторное сокращение ISA
[ редактировать ]Наборы векторных команд имеют встроенные в ISA операции арифметического сокращения. Если предполагается, что n меньше или равно максимальной длине вектора, требуются всего три инструкции:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vredadd32 y, v0 # reduce-add into y
Код, когда n больше максимальной длины вектора, не намного сложнее и аналогичен первому примеру («IAXPY»).
set y, 0
vloop:
setvl t0, n # VL=t0=min(MVL, n)
vld32 v0, x # load vector x
vredadd32 y, y, v0 # add all x into y
add x, t0*4 # advance x by VL*4
sub n, t0 # n -= VL (t0)
bnez n, vloop # repeat if n != 0
ret y
Простота алгоритма поразительна по сравнению с SIMD. Опять же, как и в примере с IAXPY, алгоритм не зависит от длины (даже во встроенных реализациях, где максимальная длина вектора может быть только одна).
Аппаратные реализации могут, если они уверены, что будет получен правильный ответ, выполнять сокращение параллельно. Некоторые векторные ISA предлагают режим параллельного сокращения в качестве явной опции, когда программист знает, что любые потенциальные ошибки округления не имеют значения, и низкая задержка имеет решающее значение. [23]
Этот пример еще раз подчеркивает ключевое фундаментальное различие между настоящими векторными процессорами и SIMD-процессорами, включая большинство коммерческих графических процессоров, которые созданы на основе функций векторных процессоров.
Выводы из примеров
[ редактировать ]По сравнению с любым SIMD-процессором, претендующим на роль векторного процессора, сокращение размера программы на порядок просто шокирует. Однако этот уровень элегантности на уровне ISA имеет довольно высокую цену на аппаратном уровне:
- На примере IAXPY видно, что в отличие от процессоров SIMD, которые могут упростить свое внутреннее оборудование, избегая проблем с несогласованным доступом к памяти, векторному процессору такое упрощение не сходит с рук: пишутся алгоритмы, которые по своей сути полагаются на векторную загрузку и сохранение. успешно, независимо от выравнивания начала вектора.
- Хотя из примера сокращения видно, что, помимо инструкций перестановки , SIMD по определению полностью избегает межполосных операций (элемент 0 может быть добавлен только к другому элементу 0), векторные процессоры решают эту проблему напрямую. То, что программисты вынуждены делать в программном обеспечении (используя перетасовку и другие трюки, чтобы переместить данные в правильную «дорожку»), векторные процессоры должны делать аппаратно, автоматически.
В целом, тогда есть выбор: либо иметь
- сложное программное обеспечение и упрощенное оборудование (SIMD)
- упрощенное программное обеспечение и сложное аппаратное обеспечение (векторные процессоры)
Именно эти резкие различия отличают векторный процессор от процессора с SIMD.
Возможности векторного процессора
[ редактировать ]Хотя многие SIMD ISA заимствованы или вдохновлены приведенным ниже списком, типичными функциями векторного процессора являются: [24] [25] [26]
- Векторная загрузка и сохранение . Векторные архитектуры с принципом «регистр-регистр» (аналогично архитектурам загрузки-сохранения для скалярных процессоров) имеют инструкции для передачи нескольких элементов между памятью и векторными регистрами. Обычно поддерживаются несколько режимов адресации. Режим адресации с единичным шагом имеет важное значение; современные векторные архитектуры обычно также поддерживают произвольные постоянные шаги, а также режим адресации рассеяния/сбора (также называемый индексированным ). Расширенные архитектуры могут также включать поддержку сегментной загрузки и сохранения, а также с учетом отказа варианты стандартной векторной загрузки и сохранения . Сегментная загрузка считывает вектор из памяти, где каждый элемент представляет собой структуру данных, содержащую несколько членов. Члены извлекаются из структуры данных (элемента), и каждый извлеченный член помещается в отдельный векторный регистр.
- Маскированные операции – маски предикатов позволяют использовать параллельные конструкции if/then/else без использования ветвей. Это позволяет векторизовать код с условными операторами.
- Сжатие и расширение — обычно с использованием битовой маски данные линейно сжимаются или расширяются (перераспределяются) в зависимости от того, установлены или очищены биты в маске, при этом всегда сохраняется последовательный порядок и никогда не дублируются значения (в отличие от Gather-Scatter, также известного как перестановка) . Эти инструкции имеются в AVX-512 .
- Зарегистрируйте Gather, Scatter (также известный как перестановка) [27] – менее ограничительный, более общий вариант темы сжатия/расширения, который вместо этого использует один вектор для указания индексов, которые будут использоваться для «переупорядочения» другого вектора. Сбор/рассеивание сложнее реализовать, чем сжатие/расширение, и, будучи по своей сути непоследовательными, могут мешать связыванию векторов . Не путать с режимами загрузки/сохранения памяти Gather-Scatter , векторные операции Gather/Scatter действуют на векторные регистры и вместо этого часто называются инструкцией перестановки .
- Splat и Extract — полезны для взаимодействия между скаляром и вектором, они передают одно значение по вектору или извлекают один элемент из вектора соответственно.
- Йота — очень простая и стратегически полезная инструкция, которая последовательно распределяет непосредственные значения на последовательные элементы. Обычно начинается с нуля.
- Сокращение и итерация — операции, которые выполняют преобразование вектора (например, находят одно максимальное значение всего вектора или суммируют все элементы). Итерация имеет вид
x[i] = y[i] + x[i-1]
где Приведение имеет видx = y[0] + y[1]… + y[n-1]
- Поддержка умножения матриц - либо путем алгоритмической загрузки данных из памяти, либо путем переупорядочения (перераспределения) обычно линейного доступа к векторным элементам, либо путем предоставления «аккумуляторов», матрицы произвольного размера могут эффективно обрабатываться. IBM POWER10 предоставляет инструкции MMA [28] хотя для произвольной ширины матрицы, которая не соответствует точному размеру SIMD, необходимы методы повторения данных, что приводит к расточительству ресурсов регистрового файла. [29] [30] NVidia предоставляет высокоуровневый API-интерфейс Matrix CUDA , хотя внутренние подробности недоступны. [31] Наиболее ресурсоэффективным методом является изменение порядка доступа к линейным векторным данным на месте.
- Расширенные математические форматы - часто включают поля Галуа арифметику , но могут включать двоично-десятичную или десятичную фиксированную точку, а также поддержку гораздо более крупных (произвольной точности) арифметических операций за счет поддержки параллельного переноса и переноса.
- Битовые манипуляции , включая векторизованные версии операций перестановки на битовом уровне, вставку и извлечение битовых полей, операции центрифугирования, подсчет населения и многие другие .
Функции векторной обработки графического процессора
[ редактировать ]Поскольку многим приложениям 3D- шейдеров требуются тригонометрические операции, а также короткие векторы для общих операций (RGB, ARGB, XYZ, XYZW), в современных графических процессорах обычно присутствует поддержка следующих функций в дополнение к тем, которые имеются в векторных процессорах:
- Субвекторы - элементы обычно могут содержать два, три или четыре подэлемента (vec2, vec3, vec4), где любой заданный бит маски предиката применяется ко всему vec2/3/4, а не к элементам в подвекторе. Подвекторы также вводятся в RISC-V RVV (называемый «LMUL»). [32] Субвекторы являются важной неотъемлемой частью спецификации Vulkan SPIR-V .
- Sub-vector Swizzle - также известный как «Перетасовка полос», который позволяет выполнять межэлементные вычисления подвекторов без необходимости дополнительных (дорогостоящих и расточительных) инструкций для перемещения подэлементов в правильные «дорожки» SIMD, а также сохраняет биты маски предиката. По сути, это мини-перестановка субвектора, которая широко используется в двоичных файлах 3D-шейдеров и достаточно важна, чтобы быть частью спецификации Vulkan SPIR-V . Broadcom Videocore IV использует терминологию «вращение полос». [33] где остальная часть индустрии использует термин «swizzle» . [34]
- Трансцендентные операции — тригонометрические операции, такие как синус , косинус и логарифм, очевидно, гораздо чаще используются в 3D, чем во многих требовательных рабочих нагрузках HPC . Однако интересно то, что скорость гораздо важнее точности в 3D для графических процессоров, где вычисление координат пикселей просто не требует высокой точности. Спецификация Vulkan учитывает это и устанавливает удивительно низкие требования к точности, поэтому аппаратное обеспечение графического процессора может снизить энергопотребление. Концепция снижения точности там, где она просто не нужна, исследуется в расширении MIPS-3D .
Ошибка (или сбой) в первую очередь
[ редактировать ]Представленная в ARM SVE2 и RISC-V RVV концепция спекулятивных последовательных векторных нагрузок. ARM SVE2 имеет специальный регистр под названием «Регистр первого отказа». [35] где RVV изменяет (усекает) длину вектора (VL). [36]
Основной принцип ffirst состоит в том, чтобы попытаться выполнить большую последовательную векторную загрузку, но позволить аппаратному обеспечению произвольно усекать фактический загруженный объем либо до объема, который будет успешным без возникновения ошибки памяти, либо просто до объема (больше нуля), который самый удобный. Важным фактором является то, что последующие инструкции уведомляются или могут точно определить, сколько загрузок действительно было успешным, используя это количество для выполнения работы только с теми данными, которые были фактически загружены.
Сравните эту ситуацию с SIMD, который представляет собой фиксированную (негибкую) ширину загрузки и фиксированную ширину обработки данных, неспособный справиться с нагрузками, выходящими за границы страниц, и даже если бы они были, они неспособны адаптироваться к тому, что на самом деле удалось, но, как это ни парадоксально, если бы SIMD-программа даже попыталась заранее (в каждом внутреннем цикле, каждый раз) выяснить, что может быть оптимально успешным, эти инструкции будут только снижать производительность, поскольку они по необходимости будут частью критического внутреннего цикла.
Это начинает намекать на причину, по которой ffirst является настолько инновационным, и лучше всего иллюстрируется memcpy или strcpy при реализации со стандартным 128-битным непредикативным SIMD без ffirst. Для IBM POWER9 количество оптимизированных вручную инструкций для реализации strncpy превышает 240. [37] Напротив, та же самая процедура strncpy в оптимизированном вручную ассемблере RVV состоит всего из 22 инструкций. [38]
Приведенный выше пример SIMD потенциально может привести к сбою и сбою в конце памяти из-за попыток прочитать слишком много значений: он также может вызвать значительное количество ошибок страниц или несовпадений из-за аналогичного пересечения границ. Напротив, предоставляя векторной архитектуре свободу решать, сколько элементов загружать, первая часть strncpy, если она изначально начинается на неоптимальной границе памяти, может возвращать ровно столько загрузок, чтобы на последующих итерациях цикла пакеты векторизованного чтения памяти оптимально согласованы с базовыми кэшами и структурами виртуальной памяти. Кроме того, аппаратное обеспечение может использовать возможность завершить чтение памяти любой данной итерации цикла точно на границе страницы (избегая дорогостоящего второго поиска TLB), при этом спекулятивное выполнение подготавливает следующую страницу виртуальной памяти, пока данные все еще обрабатываются в текущей. петля. Все это определяется железом, а не самой программой. [39]
Производительность и ускорение
[ редактировать ]Пусть r будет коэффициентом скорости вектора, а f будет коэффициентом векторизации. Если время, затрачиваемое векторным модулем на добавление массива из 64 чисел, в 10 раз быстрее, чем у его эквивалентного скалярного аналога, r = 10. Кроме того, если общее количество операций в программе равно 100, из которых только 10 являются скалярными. (после векторизации), то f = 0,9, т. е. 90% работы выполняется векторным блоком. Отсюда следует достижимое ускорение:
Таким образом, даже если производительность векторного блока очень высока ( ) есть ускорение меньше, чем , что предполагает, что отношение f имеет решающее значение для производительности. Это соотношение зависит от эффективности компиляции, например от смежности элементов в памяти.
См. также
[ редактировать ]- SX-архитектура
- Таксономия Дункана конвейерных векторных процессоров
- ГПГПУ
- Вычислительное ядро
- Потоковая обработка
- Автоматическая векторизация
- Цепочка (векторная обработка)
- Компьютер для работы с функциями
- RISC-V , открытый стандарт ISA со связанным векторным расширением переменной ширины .
- Бочковой процессор
- Тензорный процессор
- История суперкомпьютеров
- Суперкомпьютерная архитектура
Ссылки
[ редактировать ]- ^ Паркинсон, Деннис (17 июня 1976 г.). «Компьютеры тысячами» . Новый учёный . стр. 626–627 . Проверено 7 июля 2024 г.
- ^ Б. Н. Малиновский (1995). История компьютерных технологий в их лицах (на русском языке) . НАБОР. ISBN 5770761318 .
- ^ Группа вертикальных исследований MIAOW
- ^ Графический процессор МИАОВ
- ^ «Andes анонсирует многоядерный 1024-битный векторный процессор RISC-V: AX45MPV» (пресс-релиз). GlobeNewswire. 7 декабря 2022 г. Проверено 23 декабря 2022 г.
- ^ Мияока, Ю.; Чой, Дж.; Тогава, Н.; Янагисава, М.; Оцуки, Т. (2002). Алгоритм формирования аппаратного блока для синтеза процессорного ядра с упакованными инструкциями типа SIMD . Азиатско-Тихоокеанская конференция по схемам и системам. Том. 1. С. 171–176. дои : 10.1109/APCCAS.2002.1114930 . hdl : 2065/10689 .
- ^ «Riscv-v-spec/V-spec.adoc в мастере · riscv/Riscv-v-spec» . Гитхаб . 16 июня 2023 г.
- ^ «Справочное руководство по языку ассемблера Vector Engine» (PDF) . 16 июня 2023 г.
- ^ «Документация — Arm Developer» .
- ^ «Векторная архитектура» . 27 апреля 2020 г.
- ^ Векторные и SIMD процессоры, слайды 12-13.
- ^ Массив и векторная обработка, слайды 5-7
- ^ SIMD против Vector GPU, слайды 22-24
- ^ Паттерсон, Дэвид А .; Хеннесси, Джон Л. (1998). Организация и проектирование компьютера: аппаратно-программный интерфейс, стр. 751-2 (2-е изд.). Морган Кауфманн. п. 751-2 . ISBN 155860491X .
- ^ «Riscv-v-spec/V-spec.adoc в мастере · riscv/Riscv-v-spec» . Гитхаб . 19 ноября 2022 г.
- ^ Руководство программиста Videocore IV
- ^ Анализ Videocore IV QPU Джеффа Буша
- ^ «Кодирование для неона. Часть 3. Умножение матриц» . 11 сентября 2013 г.
- ^ SIMD считается вредным
- ^ Учебное пособие по ARM SVE2
- ^ «Sse — трансляция 1 к 4 и уменьшение 4 к 1 в AVX-512» .
- ^ «Сборка — самый быстрый способ выполнить горизонтальную векторную сумму SSE (или другое сокращение)» .
- ^ «Riscv-v-spec/V-spec.adoc в мастере · riscv/Riscv-v-spec» . Гитхаб . 19 ноября 2022 г.
- ^ Обзор Крея
- ^ RISC-V РВВ ISA
- ^ Обзор SX-Арора
- ^ Инструкции по сбору и разбросу регистров RVV
- ^ «Процессор IBM POWER10 — Уильям Старк и Брайан В. Томпто, IBM» . Ютуб . Архивировано из оригинала 11 декабря 2021 г.
- ^ Морейра, Хосе Э.; Бартон, Кейт; Баттл, Стивен; Бергнер, Питер; Бертран, Рамон; Бхат, Пунит; Кальдейра, Педро; Эдельсон, Дэвид; Фоссум, Гордон; Фрей, Брэд; Иванович, Неманья; Кершнер, Чип; Лим, Винсент; Капур, Шакти; Тулио Мачадо Фильо; Сильвия Мелитта Мюллер; Олссон, Бретт; Садашивам, Сатиш; Салейл, Батист; Шмидт, Билл; Шринивасарагаван, Раджалакшми; Шриватсан, Шричаран; Томпто, Брайан; Вагнер, Андреас; Ву, Нельсон (2021). «Матричное математическое средство для процессоров Power ISA (TM)». arXiv : 2104.03142 [ cs.AR ].
- ^ Крикелис, Анаргирос (1996). «Модульный массово-параллельный процессор для обработки объемных визуализаций» . Высокопроизводительные вычисления для компьютерной графики и визуализации . стр. 101–124. дои : 10.1007/978-1-4471-1011-8_8 . ISBN 978-3-540-76016-0 .
- ^ «Руководство по программированию CUDA C++» .
- ^ LMUL > 1 в RVV
- ^ Заброшенный патент США US20110227920-0096.
- ^ Видеокор IV QPU
- ^ Введение в ARM SVE2
- ^ Загрузка при первой ошибке RVV
- ^ ИСПРАВЛЕНИЕ к libc6 для добавления оптимизированной strncpy POWER9.
- ^ Пример stncpy RVV
- ^ Статья ARM SVE2 Н. Стивенса