Вычисления в памяти (in-memory compute) давно привлекают внимание индустрии: обработка данных внутри самого чипа памяти может использовать более высокую внутреннюю пропускную способность и избегать длинного пути между DRAM и обычными вычислительными ядрами. На Hot Chips 2026 Samsung показала очередной шаг в этом направлении — технологию PIM (Processing-in-Memory), встраивающую MAC-блоки прямо в чипы LPDDR5X, сохраняя при этом совместимость со стандартным контроллером памяти.

Чипы DRAM внутри разделены на банки, каждый со своей логикой чтения и записи. При обычном обращении к памяти контроллер выбирает банк, активирует строку внутри него, а затем обращается к данным через команды CAS (column access strobe). Пропускная способность при этом ограничена внешним интерфейсом чипа: даже если бы контроллер мог активировать все банки одновременно, он всё равно не смог бы получить доступ к суммарной пропускной способности всех банков сразу.

LPDDR5X-PIM от Samsung устроен как обычный чип LPDDR5X-9600 с 16 банками, но в каждый банк добавлен блок PIM. Эти блоки обращаются к своему банку DRAM напрямую, минуя ограничения внешней шины чипа. Вместе они используют внутреннюю пропускную способность всех 16 банков — итого 614 ГБ/с. Для сравнения: обычные обращения к DRAM могут задействовать параллельно только два банка и ограничены 76,8 ГБ/с.

Внутри блок PIM состоит из дерева MAC-операций с окружающими регистровыми файлами и логикой управления. Регистровый файл инструкций на 1024 бита хранит до 64 16-битных инструкций. Регистровый файл источников на 4 Кбит предназначен для векторов активации и подаёт один из операндов для массива MAC. Samsung рассчитывает, что программное обеспечение будет загружать веса модели в DRAM, поэтому подключённый банк DRAM поставляет второй операнд. Веса модели можно масштабировать перед вычислением MAC — коэффициенты масштаба берутся из 2-килобитного регистра масштаба.

Массив MAC блока PIM поддерживает несколько форматов пониженной точности. Судя по цифрам из презентации Samsung, каждый блок PIM способен выполнять четыре операции MAC в формате INT8 или FP8 за такт данных (или восемь за цикл без учёта двойной скорости передачи данных). Для 4-битных весов пропускная способность удваивается, доводя суммарную производительность чипа до 2,4 TOPS.

Это не самая впечатляющая цифра сама по себе, но реализация с несколькими чипами LPDDR5X даст более высокую суммарную производительность. Например, восемь чипов LPDDR5X вместе обеспечили бы 9,6 INT8 TOPS — что примерно соответствует NPU в Intel Meteor Lake. Правда, такая конфигурация обошлась бы недёшево: восемь 16-гигабайтных чипов LPDDR5X — это 128 ГБ системной памяти.

Доступ к вычислениям через стандартные команды DDR

Одна из главных особенностей LPDDR5X-PIM — работа в рамках стандартного протокола LPDDR5X при этом с открытием вычислительных возможностей, которых нет в стандарте памяти. Samsung добивается этого, резервируя специальные адреса строк, работающие подобно MMIO-адресам. У каждого канала есть пара предопределённых строк для управления режимом: активация одной переводит чип в однобанковый режим, другой — в многобанковый. Однобанковый режим — это обычный режим работы, а многобанковый применяет команды сразу ко всем 16 банкам, задействуя внутреннюю пропускную способность чипа.

Специальные строки на уровне банка меняют поведение команд чтения и записи. Активация такой строки заставляет команды чтения и записи обращаться к регистрам PIM вместо содержимого обычного банка DRAM (режим PIM Registers Activated). Samsung описывает сценарий использования в машинном обучении: программное обеспечение загружает веса модели в DRAM, пока чип находится в обычном однобанковом режиме. Затем программа переключает чип в многобанковый режим и входит в режим PIM Registers Activated. Это позволяет коду записывать значения активаций в регистры источников PIM, задавать коэффициенты масштаба в регистрах масштаба PIM и указывать операцию, которая заносится в регистры инструкций PIM.

Поскольку чип находится в многобанковом режиме, каждая запись регистра PIM транслируется сразу на все 16 банков. Таким образом вычисления PIM работают как очень ограниченный SIMD-процессор, где операция, коэффициент масштаба и один из операндов-источников одинаковы для всех банков. Samsung допускает запись регистров PIM и в однобанковом режиме, но это предназначено только для отладки. Каждый пакет DRAM составляет 256 бит (BL=16), заполнение одного регистра источника требует 16 команд записи. Выполнение этого по одному банку за раз для всех 16 банков потребовало бы 256 команд записи, превращая пропускную способность записи регистров PIM хостом в узкое место.

После заполнения регистров PIM программа переключается обратно в многобанковый режим и выдаёт команды чтения. Вместо чтения содержимого DRAM эти команды запускают вычисления, а результаты накапливаются в регистровых файлах векторов PIM (VRF). Затем команды записи указывают блокам PIM записать содержимое VRF обратно в банки DRAM.

PIM приходится справляться с переупорядочиванием, которое обычно выполняет контроллер памяти. Когда код настраивает PIM, активируя банк, регистровые файлы инструкций PIM по умолчанию настраиваются так, чтобы инструкции последовательно обращались к каждому элементу регистра источника: первая инструкция — к первому элементу, вторая — ко второму и так далее. Однако эта схема ломается, если контроллер памяти переупорядочивает обращения. Samsung решает эту проблему с помощью режима Address Align Mode (AAM), в котором каждая инструкция определяет индекс элемента регистра источника исходя из адреса столбца, к которому идёт обращение.

Когда хосту нужно завершить использование вычислений в памяти и прочитать результаты, он переключает чип DRAM обратно в однобанковый режим. После этого обычные команды чтения и записи DRAM снова начинают работать в штатном режиме.

Проблемы для программного обеспечения

Во внутренних тестах Samsung LPDDR5X-PIM показала значительный прирост производительности по сравнению со стандартным LPDDR5X. Способность чипа работать со стандартным контроллером памяти впечатляет, а подход инженеров Samsung к решению этой задачи выглядит довольно изобретательным.

Использование стандартных команд DRAM должно упрощать аппаратную часть, но программные сложности выглядят серьёзными. Поскольку режимы PIM меняют смысл команд доступа к DRAM, программа не может одновременно использовать PIM и выполнять обычные обращения к памяти. Это касается и разных потоков, поскольку контроллер памяти и сам чип DRAM понятия не имеют, для какого потока выполняется обращение. Если поток, не использующий PIM, читает из памяти, пока другой поток задействует PIM, первый поток может вызвать непреднамеренное вычисление и записать некорректные данные в VRF PIM. Запись со стороны потока без PIM может привести к тому, что блоки PIM запишут данные VRF по неверному адресу.

Samsung решает эту проблему тем, что хост выделяет отдельный регион памяти под PIM.

Сложно представить простой способ сделать это в типичной системе без потерь по пропускной способности памяти и производительности PIM.
Обычно аппаратура чередует адреса между каналами, что позволяет типичным паттернам доступа естественным образом задействовать пропускную способность этих каналов. PIM использует построчные регистры на уровне канала для управления переключением однобанкового/многобанкового режима, поэтому отказ от чередования и выделение отдельных каналов памяти исключительно под PIM — единственный разумный способ создать регион PIM. При этом приложения, не использующие PIM, теряют доступ к пропускной способности каналов, зарезервированных под PIM. А код PIM, в свою очередь, теряет доступ к пропускной способности и вычислениям каналов без PIM. Последнее может стать серьёзной проблемой, поскольку вычислительная производительность на чип не так уж высока.

Проблемы многозадачности могут сохраняться даже после выделения региона под PIM. Если приложение хочет использовать PIM вместе с многопоточностью, ему придётся защищать обращения к региону PIM блокировками, чтобы избежать ситуаций, когда один поток выполняет вычисления PIM, а другой одновременно пытается выполнить обычное обращение к памяти. Ситуация усложняется ещё сильнее в современной многозадачной операционной системе, где сразу несколько процессов могут пытаться использовать PIM, не зная друг о друге.

Не уверен, что есть хороший способ справиться с этим, кроме как заставить ОС выполнять сегменты кода с вычислениями PIM с заблокированными всеми остальными потоками и отключёнными прерываниями.
Обработка прерываний или переключений контекста при использовании PIM выглядит настоящим кошмаром для ОС в любом случае. Вытеснение потока, работающего с PIM, означало бы вывод канала памяти из режима PIM и сохранение состояния PIM: ОС пришлось бы считать регистровые файлы инструкций, источников, масштаба и векторов по каждому банку и где-то их сохранить. Разрешение работы только одному потоку без переключения задач оставило бы неиспользованным потенциал многопоточной производительности и могло бы привести к проблемам с отзывчивостью системы, если код проведёт слишком много времени в секциях вычислений PIM.

Проблемы с кэшами и внеочередным исполнением

Вычисления PIM ломают ожидания подсистемы памяти относительно поведения DRAM, поскольку DRAM может генерировать значения памяти, о которых иерархия кэшей никогда не узнаёт. Кэши, в свою очередь, могут ломать поведение PIM, поглощая обращения, которые должны были запускать операции PIM. Поэтому Samsung рекомендует размечать память PIM как некэшируемую. Это проблематично, поскольку современные CPU и GPU сильно полагаются на кэширование для сглаживания задержек DRAM. Производительность на некэшируемой памяти будет крайне низкой, так как ядра CPU или GPU будут проводить гораздо больше времени в простое в ожидании памяти.

Отказ от кэширования — не единственная проблема. Чтения PIM работают подобно обращениям MMIO, поскольку они вызывают вычисления, влияющие на значения VRF PIM, а не просто извлекают данные. CPU также сглаживает задержки памяти, инициируя загрузки до того, как станет точно известно, что данные загрузки действительно понадобятся. Предсказание переходов позволяет CPU выдавать инструкции до того, как ядро точно узнает, что эти инструкции будут выполнены. Механизмы предвыборки (prefetch) наблюдают за паттернами доступа к памяти и пытаются загрузить данные в кэш до того, как инструкции их запросят. Если CPU загружает данные, которые в итоге оказываются не нужны, это не страшно, поскольку обычные загрузки не приводят к некорректному поведению программы. К сожалению, для PIM это не так: чтения запускают вычисления, изменяющие содержимое VRF PIM.

Да, это точно кончится плохо

Работа с регионом PIM, скорее всего, потребует делать обращения к памяти не только некэшируемыми, но и неспекулятивными. Работа CPU без кэширования, предвыборки и внеочередного исполнения серьёзно ударит по производительности.

Общие сложности вычислений в памяти

Помимо трудностей с режимами PIM, вычисления в памяти создают и более общие проблемы для программного обеспечения. Каждый блок PIM имеет быстрый доступ только к своему локально подключённому банку DRAM. Все остальные входные данные приходится доставлять через сравнительно ограниченный внешний интерфейс чипа DRAM. Блоки PIM не могут напрямую обмениваться данными друг с другом, поэтому если одному блоку PIM нужно использовать результаты, сгенерированные другим, хосту приходится перемещать данные с помощью обычных операций чтения и записи DRAM.

Заключение

Теоретически LPDDR5X-PIM от Samsung может попасть в любой сервер, настольный компьютер, ноутбук или даже мобильное устройство благодаря способности работать со стандартными контроллерами памяти. Однако это не значит, что технологию будет легко использовать с типичными аппаратными и программными парадигмами. Переключение режимов PIM создаёт серьёзные препятствия для многозадачных операционных систем. Изменение содержимого DRAM «под капотом» и привязка побочных эффектов к командам чтения ломает кэширование, предвыборку и внеочередное исполнение процессора.

Модули памяти. Не то поколение, но по цене за гигабайт, вероятно, близко

Едва ли существует простой способ использовать вычисления в памяти без изменений во всей подсистеме памяти. Например, облегчить внедрение на уровне ПО могли бы следующие шаги:

  • Расширить интерфейс DRAM, добавив набор вычислительных команд, чтобы избежать сложностей с переключением режимов

  • Заставить контроллер памяти вести себя как равноправное вычислительное ядро с точки зрения когерентности кэша. Перед использованием команд вычислений в памяти контроллер памяти выдаёт запросы read-for-ownership (RFO) для всех затрагиваемых строк кэша. Это позволяет контроллеру памяти получить любые изменённые данные и записать их обратно в DRAM перед началом вычислений в памяти, гарантируя, что результаты вычислений в памяти отражают последние записи со стороны CPU. Затем контроллер памяти удерживает владение затронутыми строками кэша до завершения операций вычислений в памяти, позволяя ядрам CPU наблюдать результаты вычислений в памяти без необходимости инвалидировать или обходить кэши

  • Добавить новый набор инструкций CPU наподобие «rep macb», выполняющих операции умножения-накопления над блоком памяти с фиксированными множителями/коэффициентами масштаба и неопределёнными числовыми характеристиками. CPU сможет сам выбирать, использовать ли вычисления в памяти (если DRAM их поддерживает) или сгенерировать последовательность внутренних операций (если работа идёт с небольшим набором данных, уже находящимся в кэше).

При таких аппаратных изменениях программное обеспечение смогло бы использовать вычисления в памяти из многозадачной операционной системы без резервирования памяти и без потери параллелизма на уровне потоков из-за блокировок и синхронизации, связанных с PIM. Прозрачная инструкция CPU избавляет от проблемы поставки бинарников под конкретное железо и позволяет писать код, совместимый с будущими версиями, автоматически использующий новые аппаратные возможности, включая разные реализации вычислений в памяти. Это также позволяет аппаратуре использовать знания о конкретной реализации и данные в реальном времени (например, поиск в кэше без заполнения при промахе), чтобы принимать оптимальное решение о том, где выполнять вычисления.

Не нравится программная альтернатива с резервированием регионов памяти, разметкой их как некэшируемых и блокировкой потоков — слишком много компромиссов по производительности, объёму памяти и отзывчивости системы.