Сейчас не так важно что за SIMD 128-512 поддерживается, так как в железе может быть 4х 128битных пайплайна, то есть 4 инструкции выполняются параллельно. Такое сделано например на Intel E-ядрах и Cortex X4. А на AMD Zen4 был SIMD256 dual issue для эмуляции SIMD512 пока они не сделали полноценные 512 бит на Zen5.
У ЦП reorder buffer 300+ микроинструкций, задержка на чтение RAM около 60нс, на 5ГГц это 300 тактов. Так что в идеальном случае память прочитается даже без кэшей.
В некоторых случаях кэши даже вредны, например memcpy при копировании более 2Мб включает некэшируемое копирование, иначе на заполнение кэшей тратится в 3 раза больше времени.
Для корректности теста автовекторизацию лучше выключить настройками компилятора. А еще неплохо бы посчитать флопсы и Гб/с.
Насчет кэш промахов при случайном доступе нужно считать Гб/с и сравнивать с аналогичным memcpy, тогда будет видно сколько реально идет в RAM, а сколько в кэши. Ничего не мешает ЦП читать массив индексов наперед и префетчить, потери идут только из-за прыгания по кэш линиям из-за чего железо не успевает подгружать данные, а была бы память побыстрее, то и потерь не было бы.
Как в UE не знаю, но я тестировал разные варианты и на всех встройках быстрее через пиксельный и с sampler min фильтром вместо gather4. Округление до степени 2 тоже быстрее работает, хоть и меньше точности.
Только подход не универсальный, так как запись в UAV идет без компресии (кроме AMD), поэтому на встройках и мобилках такой код работает в разы медленее.
как быстро удалить элементы из x[], y[], z[] массивов
ни в коем случае не использовать скаляры, иначе производительность падает в 5 раз
как сделать ветвление: сгруппировать по типам или использовать маски
как выбрать определенные элементы из массива и плотно упаковать их не переходя на скаляры
как разместить иерархию в памяти: проще когда по 16 нод цепляется, но такого не бывает и нужно заполнить например один simd регистр из 3х родителей и второй simd из 16 их детей и не потерять на этом производительность
А если капнуть глубже, то современные ЦП способны читать из L1 в 2 регистра по 64байт выровненных данных за такт, но пока мы используем скаляры все это замедляется до 2х 4 байт за такт. И используем только одну инструкцию на скаляр вместо инструкции на 16х скаляров.
Лучше смотреть в Task Manager на Dedicated memory (VRAM) и Shared memory (RAM).
Кстати, если поставить вулкан бэкэнд, то память выделяется только в VRAM и так можно узнать максимальный контекст. Только просто выделения контекста недостаточно, нужно его еще заполнить на 100%
Суть в том что между каждым умножением на скрытый слой нужно делать ReLU или SiLU и подобные.
Gpt как раз и пишет про SiLU, что для него потребуется еще инструкции тащить. А если модели перейдут на какой-нибудь xxLU, то железку придется выкинуть и напечатать новую.
Вариант умножать в памяти, а потом загружать все на чип для SiLU и прочего не подходит. Хотя трафика в 2 раза меньше будет.
А я себе взял Intel Ultra 7 255H (6P + 8E + 2LP) на 64Гб (хотел докупить 96Гб, но не успел). У него 32гб видеопамяти, но всю использовать нельзя - не может выделить слишком большой кусок. На встройке около 20т/с, на ЦП 10-15т/с но тротлит и работает на 3.5ГГц вместо 5.1+4.5. gpt-oss-20b на встройке до 64К контекст, на ЦП все 128К. Из плюсов 2 thunderbolt и еще oculink можно воткнуть во второй m2.
На gpt-oss-20b у меня с 16гб предел 16К контекст. Кстати с CUDA бэкэндом можно сделать и больше, часть уйдет в RAM, но скорость не сильно проседает, видимо драйвер умеет переливать в VRAM часто используемые части.
Кроме операция над матрицами есть еще ReLU, где mix/max, sin, cos и тд в зависимости от архитектуры при обучении модели. Так что придется полноценный чип приделать к памяти.
gpt-oss-20b справляется не сильно хуже моделей на 1Тб, так что с ростом памяти прирост в качестве небольшой и кажется что чуть-чуть улучшить обучение маленькой модели и будет прям совсем хорошо.
Под AVX тоже есть расширения, например AVX-VNNI для Intel, который повторяет AVX512-VNNI.
Я все же про то, что решает распараллеливание инструкций, а не длина SIMD.
Сейчас не так важно что за SIMD 128-512 поддерживается, так как в железе может быть 4х 128битных пайплайна, то есть 4 инструкции выполняются параллельно. Такое сделано например на Intel E-ядрах и Cortex X4. А на AMD Zen4 был SIMD256 dual issue для эмуляции SIMD512 пока они не сделали полноценные 512 бит на Zen5.
У ЦП reorder buffer 300+ микроинструкций, задержка на чтение RAM около 60нс, на 5ГГц это 300 тактов. Так что в идеальном случае память прочитается даже без кэшей.
В некоторых случаях кэши даже вредны, например memcpy при копировании более 2Мб включает некэшируемое копирование, иначе на заполнение кэшей тратится в 3 раза больше времени.
Для корректности теста автовекторизацию лучше выключить настройками компилятора. А еще неплохо бы посчитать флопсы и Гб/с.
Насчет кэш промахов при случайном доступе нужно считать Гб/с и сравнивать с аналогичным memcpy, тогда будет видно сколько реально идет в RAM, а сколько в кэши. Ничего не мешает ЦП читать массив индексов наперед и префетчить, потери идут только из-за прыгания по кэш линиям из-за чего железо не успевает подгружать данные, а была бы память побыстрее, то и потерь не было бы.
Как в UE не знаю, но я тестировал разные варианты и на всех встройках быстрее через пиксельный и с sampler min фильтром вместо gather4. Округление до степени 2 тоже быстрее работает, хоть и меньше точности.
Тут мой ресерч по HiZ.
Только подход не универсальный, так как запись в UAV идет без компресии (кроме AMD), поэтому на встройках и мобилках такой код работает в разы медленее.
8745HS на Zen4 с llama.cpp выдает 20tps на GPU и около 12tps на CPU. На Zen5 должно быть побыстрее.
pack(1) падает на ARM, если при компиляции не разрешить чтение невыровненых данных, что замедлит весь код
С переходом на simd начинается веселье типа:
как быстро удалить элементы из x[], y[], z[] массивов
ни в коем случае не использовать скаляры, иначе производительность падает в 5 раз
как сделать ветвление: сгруппировать по типам или использовать маски
как выбрать определенные элементы из массива и плотно упаковать их не переходя на скаляры
как разместить иерархию в памяти: проще когда по 16 нод цепляется, но такого не бывает и нужно заполнить например один simd регистр из 3х родителей и второй simd из 16 их детей и не потерять на этом производительность
А если капнуть глубже, то современные ЦП способны читать из L1 в 2 регистра по 64байт выровненных данных за такт, но пока мы используем скаляры все это замедляется до 2х 4 байт за такт. И используем только одну инструкцию на скаляр вместо инструкции на 16х скаляров.
Сделал так и нашел у себя такую же ошибку.
Кстати, для ассертов уже давно добавил bool{} конструктор чтобы отлавливать неправильные касты.
Лучше тогда андроид ТВ приставку с али за 4К. Там нет видеокамеры и микрофона, 100% отключается при выдергивании из розетки.
А кто их засудит за недоступ к еще разрешенным ресурсам?
Лучше смотреть в Task Manager на Dedicated memory (VRAM) и Shared memory (RAM).
Кстати, если поставить вулкан бэкэнд, то память выделяется только в VRAM и так можно узнать максимальный контекст. Только просто выделения контекста недостаточно, нужно его еще заполнить на 100%
Суть в том что между каждым умножением на скрытый слой нужно делать ReLU или SiLU и подобные.
Gpt как раз и пишет про SiLU, что для него потребуется еще инструкции тащить. А если модели перейдут на какой-нибудь xxLU, то железку придется выкинуть и напечатать новую.
Вариант умножать в памяти, а потом загружать все на чип для SiLU и прочего не подходит. Хотя трафика в 2 раза меньше будет.
А я себе взял Intel Ultra 7 255H (6P + 8E + 2LP) на 64Гб (хотел докупить 96Гб, но не успел). У него 32гб видеопамяти, но всю использовать нельзя - не может выделить слишком большой кусок. На встройке около 20т/с, на ЦП 10-15т/с но тротлит и работает на 3.5ГГц вместо 5.1+4.5. gpt-oss-20b на встройке до 64К контекст, на ЦП все 128К. Из плюсов 2 thunderbolt и еще oculink можно воткнуть во второй m2.
На gpt-oss-20b у меня с 16гб предел 16К контекст. Кстати с CUDA бэкэндом можно сделать и больше, часть уйдет в RAM, но скорость не сильно проседает, видимо драйвер умеет переливать в VRAM часто используемые части.
Кроме операция над матрицами есть еще ReLU, где mix/max, sin, cos и тд в зависимости от архитектуры при обучении модели. Так что придется полноценный чип приделать к памяти.
gpt-oss-20b справляется не сильно хуже моделей на 1Тб, так что с ростом памяти прирост в качестве небольшой и кажется что чуть-чуть улучшить обучение маленькой модели и будет прям совсем хорошо.
Теми кто дожил до этого) Но большинство слили все с убытком чтобы расплатиться за кредиты.