AMD обеспечивает работу ведущих мировых систем научных вычислений: от экзафлопсных суперкомпьютеров, способствующих открытиям в США и Европе, до Lux, первой системы Genesis Mission для науки, управляемой ИИ. Благодаря передовым процессорам CPU, GPU, FPGA, сетевым технологиям и программному обеспечению ROCm™, AMD предоставляет странам, лабораториям и предприятиям единую открытую платформу для высокопроизводительных вычислений, ИИ для науки, суверенного ИИ, агентного ИИ и пути к квантовым вычислениям. На этом пути первой областью, где квантовые и классические вычисления должны работать как единое целое, является исправление ошибок.
Отказоустойчивые квантовые вычисления зависят от классического контура обратной связи, который должен успевать за кубитами: данные измерений должны поступать на классический вычислитель, декодироваться и возвращаться в виде коррекции вовремя. AMD и Qblox совместно создают этот контур. Qblox предоставляет стек управления: Cluster, модульную стойку синхронизированных модулей управления и считывания, чьи секвенсоры Q1 выполняют эксперимент, связанные сетью обратной связи LINQ и работающие синхронно благодаря SYNQ. AMD берет на себя все остальное: адаптивные SoC и FPGA, графические процессоры Instinct™ и серверные процессоры EPYC™. На своем пути этот контур пересекает две границы. Первая находится внутри стека управления, где модули на базе FPGA координируют выполнение цепей и считывание кубитов. Вторая — между стеком управления и классической вычислительной структурой, которая вычисляет алгоритмы квантовой коррекции ошибок.
Рисунок 1: Квантовый процессор, его система управления и классические вычислительные CPU, GPU и FPGA от AMD, обменивающиеся синдромами и коррекциями
Эта статья посвящена второй границе и дает ответы на два аспекта. Во-первых, мы создаем прямое соединение между системой управления и памятью любого ускорителя с минимально возможной аппаратной задержкой. Во-вторых, мы демонстрируем модель выполнения, в которой несколько моделей программирования (Python, C, OpenMP, цепочки ядер GPU) могут обслуживать контур параллельно и взаимодействовать в режиме реального времени, чтобы код, отвечающий на измерение, мог поступать из любого источника, а не только из того, который может запустить один конкретный фреймворк. В остальной части статьи мы рассмотрим их в таком порядке: созданное нами соединение, а затем среда выполнения, обеспечивающая эту модель исполнения.
Контур с четырьмя типами процессоров
Квантовая коррекция ошибок в реальном времени должна выполнять измерение, декодирование и коррекцию в пределах окна когерентности. Система управления не может бесконечно ждать ответа: квантовая программа может продолжаться, пока данные QEC декодируются. Результат декодера должен быть готов до первой операции или интерпретации измерения, которая от него зависит; именно это здесь означает «вовремя».
Один цикл исправления ошибок выглядит так:
- Система управления публикует измерения синдромов.
- Карта связи записывает их в очередь в памяти ускорителя.
- Код на ускорителе декодирует их.
- Возвращается коррекция.
- Квантовая программа продолжает работу с примененной коррекцией.
Декодирование — это причина, по которой контур должен быть быстрым, а устройства — взаимодействовать с низкой задержкой. Однако другие части программы или системы также выиграют от низкой задержки, например, калибровка, телеметрия, элементы управления (отслеживание дрейфа, адаптивное измерение, решения об активном сбросе) и классические вычислительные этапы всего приложения. Чем дальше вы отходите от декодирования, тем меньше этот код является фиксированной функцией и тем больше он становится обычным программным обеспечением: написанным на существующих языках, вызывающим существующие библиотеки, созданным с использованием существующих моделей программирования. Хотя в этой статье мы фокусируемся на случае декодирования, созданный нами путь в равной степени подходит и для других задач.
Это делает внешний контур, управление и классические вычисления задачей гетерогенных вычислений. Декодеры уже созданы для FPGA, CPU и GPU, а калибровочный и прикладной код, который следует за ними, будет иметь такой же набор вариантов; где каждый фрагмент работает лучше всего — все еще открытый вопрос. Пока это не определено, соединение не должно выбирать победителя: управляющая FPGA, GPU, CPU и адаптивные SoC должны иметь возможность находиться в одном контуре. Поэтому мы разделяем три задачи, каждую из которых можно заменить отдельно: что физически переносит биты (физический уровень связи), как устройства передают друг другу работу и ответы (то, что мы называем уровнем обмена), и что вычисляет (среда выполнения). Мы начнем с соединения.
Рисунок 2: Вычисления, обмен, провод. Графические процессоры AMD Instinct, процессоры AMD EPYC и адаптивные SoC AMD Versal находятся на одном уровне обмена в памяти устройства; физическая связь под ним заменяема, а слот, помеченный +, открыт для будущей интеллектуальной собственности.
Созданное нами соединение: от кабеля Aurora до памяти ускорителя
От кабеля до памяти ускорителя
Рисунок 3: Созданное нами соединение. Канал Aurora передает кадры от системы управления на карту связи AMD Alveo™ U55C, которая направляет каждый запрос непосредственно в память ускорителя через PCIe и отправляет ответ обратно тем же путем.
Система управления подключается к карте связи AMD Alveo™ U55C через Aurora 64B/66B, легкий протокол последовательной передачи данных «точка-точка» от AMD: четыре линии по 10,3125 Гбит/с каждая, без потерь и с сохранением порядка, с внутриполосным управлением потоком. Внутри карты плагин Aurora передает целые кадры мостовому ядру в виде 512-битных слов на частоте 250 МГц. Затем механизм уровня обмена записывает каждый запрос прямо в очередь в памяти ускорителя с помощью операций записи PCIe peer-to-peer. После слова последовательности с последним маркером уровень обмена отслеживает очередь ответов в собственной памяти FPGA, которую ускоритель заполняет операциями записи. Никакое программное обеспечение на хосте не касается кадра. Обратите внимание, что очередь запросов стратегически размещена в памяти ускорителя, в то время как очередь ответов размещена внутри FPGA. Это сделано для облегчения механизма опроса с каждой стороны.
Само соединение недорогое. Через кабель и этапы связи обеих карт кадр и его ответ проходят за 0,44 мкс; передача запроса в память ускорителя занимает 10 нс, чтение ответа из памяти карты — 40 нс, и отправка его обратно — 30 нс: всего около половины микросекунды.¹ Остальное время кругового пути — это обнаружение запроса ускорителем, вычисление и публикация ответа, что является началом следующего цикла работы.
Использование физического канала Aurora не является обязательным. Плагин Aurora находится за своим собственным контрактом: доставлять целые кадры, без потерь и в порядке очереди, и подсчитывать каждую ошибку. Ничто выше него не является специфичным для Aurora, поэтому другой последовательный протокол, соблюдающий этот контракт, может быть внедрен без изменения механизма, очередей или среды выполнения. Эта связь работает между системой управления и хостом ускорителя; это не последовательная структура между модулями управления внутри стека управления, то есть первая граница.
Две очереди, публикация последней
Уровень обмена состоит из двух очередей:
- очередь запросов в памяти потребителя, где производитель записывает слот, а затем слово последовательности, последним;
- очередь ответов в памяти производителя, где потребитель записывает ответ, выдает барьер освобождения, а затем слово готовности, последним.
Рисунок 4: Как формируется сообщение. При классическом кодировании данные идут первыми, а одно слово, записываемое последним, публикует их; ответ добавляет барьер освобождения (release fence) перед словом готовности. При поэлементном кодировании каждый 16-байтовый фрагмент содержит порядковый номер сообщения, поэтому каждый фрагмент является самопроверяемым.
Каждая сторона опрашивает только свою собственную память, поэтому «горячий путь» (hot path) никогда не считывает данные через PCIe. Опубликованное слово — это «дверной звонок» (doorbell), который перемещается вместе с полезной нагрузкой в обоих направлениях. Поскольку полезные нагрузки измерений занимают всего несколько байтов, они помещаются рядом с «дверным звонком», что позволяет избежать отдельного извлечения данных и их кругового перемещения. Слот используется повторно только после того, как ответ на него был обработан. Барьер освобождения делает слово готовности надежным: без него карта могла бы увидеть слово готовности раньше байтов ответа. Каждый потребитель поддерживает эту гарантию самым дешевым способом: барьер на GPU или CPU, порядок записи PCIe на V80 и, во втором варианте кодирования ниже, полное отсутствие слова публикации.
Очереди также представлены во втором варианте кодирования для потребителей, которым это выгодно. Вместо одного слова публикации на сообщение, каждый 16-байтовый фрагмент сообщения несет порядковый номер сообщения, поэтому считыватель может доверять каждому фрагменту в момент его прибытия, без отдельного слова публикации и без барьера после данных. Сегодня GPU используют его в обоих направлениях для встроенного эха среды выполнения, которое и измеряют показатели задержки ниже, как и CPU EPYC 7282 при 64 байтах; сессии, обслуживающие пользовательские функции, по-прежнему используют классическое кодирование.²
Три теста обмена показывают, что разделение сохраняется. Измените физический путь, и потребитель не изменится: ядро GPU никогда не узнает, какой канал доставил кадр. Измените потребителя, и производитель не изменится: заставить CPU потреблять цикл карты не потребовало изменений в логике карты, ее образе, драйвере или ABI, и тот же образ карты также обслуживал адаптивную SoC. И, как показывает следующий раздел, измените модель программирования, и оба конца останутся прежними.
Хост только выполняет настройку
Работа хоста заканчивается до прибытия первого кадра. При запуске сессии он связывает среду выполнения и ваши функции в постоянное ядро, выделяет очереди запросов и ответов и закрепляет их в памяти устройства, а также отображает каждую очередь так, чтобы ее партнер мог записывать в нее напрямую через PCIe. Затем он программирует карту связи адресами очередей, запускает постоянное ядро и отходит в сторону. С этого момента путь кадра включает только устройства. Карта записывает каждый запрос прямо в память ускорителя; ускоритель, опрашивая собственную память, находит его, отвечает на него и записывает ответ прямо в память карты; а карта, опрашивая собственную память, забирает ответ. Никакое прерывание, вызов драйвера или поток хоста не затрагивают кадр, поэтому для встроенных функций на пути кадра нет вызовов хоста.
Чтобы проверить это, мы заморозили процесс хоста в середине выполнения, остановив каждый из его потоков, в то время как карта продолжала отправлять запросы и проверять каждый ответ. GPU и V80 продолжали отвечать на протяжении всей заморозки, без сбоев верификации, и выполнение продолжалось нормально после возобновления процесса.² Потребитель CPU является исключением по своей структуре, поскольку его потребителем является поток хоста. Однако можно создать среду выполнения, которая отделяет потоки, осуществляющие связь, от тех, которые выполняют работу. Пути OpenMP и цепочки, описанные в следующем разделе, также сохраняют свои собственные роли хоста: другая среда выполнения запускает область OpenMP, а поток хоста перезапускает цепочку ядер.
Логика на том же уровне обмена
Ускоритель вычислений AMD Alveo™ V80 встречается с тем же уровнем обмена в программируемой логике: он запрашивает запросы, проверяет их и записывает ответы со словом публикации в конце, без чтения по PCIe на любой из карт. В наших экспериментах используются небольшие декодеры поиска для кодов Steane-7 и repetition-3, которые возвращают логические ошибки, равные истинным значениям.² Логика присоединяется к циклу рядом с GPU и CPU, потому что стык находится в памяти, а не в программном обеспечении хоста.
В этих измерениях на V80 работает только логика обмена, без остальной части схемы за ней, поэтому она также показывает, чего стоит система сама по себе. Ее логика отвечает через 28 нс после того, как видит запрос, однако время кругового пути составляет 2,43 мкс (медиана): почти все это — платформа. Запрос пересекает PCIe от карты связи в V80, ответ пересекает путь обратно в память карты, и карта замечает его. V80 упорядочивает каждый ответ после его данных, используя порядок, в котором PCIe доставляет отправленные записи, поэтому он никогда не ждет подтверждения записи.²
Межсоединение доставляет каждый запрос в память ускорителя и каждый ответ обратно без участия хоста. То, что отвечает на эти запросы и в какой модели программирования, — это вторая половина дизайна.
Где находится стык
В нашем дизайне стык между устройствами — это не программный интерфейс на стороне хоста. Это контракт в памяти устройства: структура байтов и правила, регулирующие, когда их можно читать и записывать. Интерфейс на стороне хоста отделяет программное обеспечение от транспорта, но каждое устройство по-прежнему зависит от библиотеки хоста на своем пути. Контракт памяти, напротив, отделяет сами устройства. Все, что считывает и записывает байты в указанном порядке, может участвовать — будь то ядро GPU, поток CPU или блок логики. Одна и та же спецификация может генерировать определения для C, Python и SystemVerilog, позволяя программному и аппаратному обеспечению реализовывать единый общий контракт.
Среда выполнения — это библиотека
Создание программного обеспечения на ускорителях всегда было сложной задачей: каждая библиотека и модель программирования привносят свою среду выполнения, очереди и предположения о том, кто владеет устройством. Мы называем эту проблему «Слишком много поваров на кухне» для сред выполнения. Ее решение заключается в создании моделей выполнения программ, которые отделены от конкретной модели программирования или языков программирования. Реальное время на квантовых компьютерах добавляет еще один уровень сложности в это уравнение.
- Работа начинается с кубита, а не с хоста. Потоки, графы и целевые области OpenMP предполагают хост-центричный взгляд, где программа CPU запускает работу. Здесь устройство запускает ее, поэтому обычная модель разгрузки работает в обратном направлении, а работа в реальном времени и околореальном времени существует в разных временных масштабах.
- Композиция не должна стоить времени. Дополнительный запуск или синхронизация — это шум при обычной разгрузке. В цикле это съедает время, отведенное на выполнение задачи.
- Устройство никогда не прекращает работу. Постоянное ядро занимает GPU, поэтому библиотеки и другие модели программирования должны сосуществовать с ним, а не сменять друг друга.
Поэтому среда выполнения QPU не может владеть main(). Вместо фреймворка, который владеет программой, мы создали агностическую по отношению к фреймворку среду выполнения устройства, которая работает везде, где уже работает ваш код, и которую могут разместить ваши существующие инструменты. Ваше приложение может быть функцией Python, функцией C или целевой областью LLVM OpenMP. Все трое являются клиентами одной библиотеки, и они дают идентичные ответы.³
Поэтому мы должны подчеркнуть, что эта работа не является предложением интерфейса для Python. Речь идет о том, как сделать программное обеспечение компонуемым в реальном времени, и наш ответ — библиотека под каждым интерфейсом. Код в этой статье взят из исследовательского прототипа: его имена и синтаксис, особенно интерфейс Python, не являются фиксированным интерфейсом. Мы выступаем за дизайн библиотеки; внешние интерфейсы поверх нее могут меняться или заменяться интерфейсами существующего фреймворка без ее изменения.
Библиотека под капотом
Библиотека среды выполнения устройства представляет собой один автономный заголовочный файл на C. Он используется в архитектурах, не имеющих логики для связи (то есть в GPU и CPU в наших примерах). Чтобы обеспечить прямую интеграцию с приложением посредством JIT, библиотека компилируется в биткод LLVM для GPU AMD и нативно для хоста, а четыре свойства проектирования делают компоновку возможной:
- Небольшой набор глаголов. Потребитель запрашивает работу с помощью next и возвращает ее с помощью complete; он читает запрос и добавляет ответ; и он компонуется с другими ядрами через сигналы, очереди на стороне устройства и графы. Любой код, который может вызывать эти глаголы, может обслуживать цикл.
- ABI, на который может ориентироваться любой фронтенд. Каждый вызов принимает и возвращает только скаляры и указатели, поэтому объявления идентичны для GPU и хоста, а фронтенд, генерирующий LLVM IR, не нуждается в покомпонентной генерации для каждого целевого устройства. Именно это делает Python, C и OpenMP равными участниками.
- Упорядочивание памяти находится исключительно внутри библиотеки. Ни один клиент не пишет барьер (fence). Самая сложная проблема корректности в реальном времени — публикация ответа только после того, как его байты становятся видимыми — решается один раз, а не каждым клиентом.
- Один целевой слой, одна спецификация байтов. Размер волны (wave size) и идентификатор полосы (lane id) поступают из целевого слоя, а не из констант, а общие типы генерируются из одной спецификации, чтобы отдельно собранные ядра согласовывались друг с другом.
Фрагмент заголовка библиотеки среды выполнения устройства (имена прототипа). Это та часть, за которую мы выступаем; все остальное в этой статье является клиентом этих вызовов. Функции, которые она обслуживает, прототип называет «обработчиками» (handlers), отсюда handler_id; в этой статье мы просто называем их функциями.
Этот паттерн покажется знакомым любому, кто работал со средой выполнения устройств OpenMP в LLVM: код для каждого целевого устройства за единым интерфейсом, поставляемый в виде биткода и связываемый на позднем этапе (linked late).
Внедрение в ядра, которые мы компилируем с помощью JIT
Ключевым аспектом достижения низкой задержки является обеспечение того, чтобы ядро, содержащее управляющую логику среды выполнения, было тем же ядром, которое выполняет код. При наличии нескольких функций (т. е. handler_ids) среда выполнения должна генерировать единое ядро, в которое встроена функциональность всех возможных ядер. Когда сеанс запускается, библиотека, ваши функции и сгенерированная таблица диспетчеризации компонуются в одно постоянное ядро: нет запуска на каждый кадр и нет вызовов хоста. Именно так компоновка позволяет избежать затрат времени. Компоновка — это одноразовые затраты при запуске сеанса: около 29 мс, когда скомпонованный образ кэшируется, и 4,8 с, когда он не кэшируется.³
Для внешних ядер мы исследуем диспетчеризацию между устройствами с помощью традиционных механизмов. Например, для GPU MI210 мы используем очереди HSA, которые позволяют постоянному управляющему ядру диспетчеризировать второе ядро.
Преимущество работы на уровне LLVM-IR и использования JIT заключается в том, что мы можем напрямую получить доступ к реализации libc для GPU (а также к другим библиотекам), как это поддерживается исходным репозиторием. Таким образом, это обеспечивает поддержку math.h «из коробки» для генерации ядер.
Клиенты GPU: фронтенды и модели программирования
В нашем прототипе среда выполнения может разместить функцию четырьмя способами: ① инлайн (встроена в постоянное ядро библиотеки), ② резидентный рабочий (resident worker — отдельное постоянное ядро, принимающее работу из очереди на стороне устройства), ③ внешний (другая модель программирования владеет ядром и вызывает next и complete) или ④ цепочка ядер (обычные ядра, предварительно подготовленные в очереди HSA, которые постоянное ядро высвобождает одной операцией сохранения, и сигнал завершения которых запускает ответ). Первые три являются клиентами библиотеки; ядрам цепочки не обязательно знать о существовании цикла. Управляющая сторона никогда не знает, кто именно ответил.
Рисунок 5: Четыре способа размещения функции. Инлайн-функции ① выполняются внутри управляющего ядра. В противном случае ядро передает фрейм дальше: через очередь задач резидентному рабочему ②, через очередь конечных точек в область OpenMP ③ или, с помощью одной операции сохранения, в цепочку обычных ядер ④, предварительно подготовленных в очереди HSA.
Фронтенд на Python является одним из возможных клиентов, обслуживаемых в инлайн-режиме ①. Он транслируется напрямую в LLVM IR, который вызывает библиотеку; входы связываются по имени со значениями, которые публикует управляющая программа, а возвращаемое значение заполняет ответ, которого ждет управляющая программа.
Листинг 1: Один из возможных фронтендов (синтаксис прототипа). b — это второй вход массива данных, используемый его функциями с двумя аргументами. math.sin здесь не из Python: он транслируется в libm от LLVM для GPU. Этот пример демонстрирует числовой код с вызовами библиотек, которые формируют этап калибровки.
На стороне графической карты плата проверила каждый из 3 × 10⁶ ответов этой функции на соответствие результату хоста без единого несоответствия. Время кругового пути (round trip) составляет 6,33 мкс (медиана): сеанс, обслуживающий пользовательские функции, в настоящее время использует общий путь среды выполнения, а не быстрый путь, который обслуживает встроенное эхо на рисунках 7 и 8.³
Продолжая другим примером, выгрузка (offloading) OpenMP в LLVM является внешним клиентом ③. Расширение LLVM ompx_bare запускает целевую область как обычное ядро с фиксированной сеткой; внутри нее область использует глаголы библиотеки для потребления кадров, адресованных одной функции:
Листинг 2: Область OpenMP в качестве клиента (сокращенно; имена прототипа). qod_next и qod_complete_rc — это весь контракт между моделью программирования и средой выполнения. Мы измерили эту область в обоих вариантах: сама по себе она запрашивает и маршрутизирует кадры внутри next; вместе с управляющим ядром среды выполнения маршрутизацию выполняет управляющее ядро.
Библиотека маршрутизирует каждый кадр в соответствии с функцией, которой он адресован, в его собственную очередь конечной точки, по одному потребителю на конечную точку; две конечные точки обслуживаются двумя группами (teams) OpenMP, каждая из которых видит только кадры, адресованные ее собственной функции.⁴ На GPU AMD нативным путем к инициируемой устройством работе является очередь HSA, собственные пакеты диспетчеризации GPU: хост подготавливает цепочку обычных ядер ④, и одна операция сохранения в память GPU запускает ее. Такой механизм может стать строительным блоком для поддержки HipGraphs. Триггер достигает первого ядра за 1,92 мкс (медиана).⁴ Поток хоста по умолчанию все еще повторно подготавливает цепочку, и 0,37–0.93 % кадров ждут этого.³
Компоновка работает, но пока не бесплатна. На стороне карты цепочка ④ публикует свой ответ на 1,2 мкс позже, чем резидентный рабочий ②, выполняющий то же тело, а область OpenMP ③ обходится на 6,5 мкс дороже, чем тот же декодер, встроенный инлайн ①, когда она маршрутизирует сама, и на 4,4 мкс дороже, когда маршрутизацию осуществляет управляющее ядро, как при 64, так и при 1792 байтах, с идентичными ответами; все значения являются медианными.³
Наряду с библиотеками, которые вы уже используете
Библиотеки libc и libm от LLVM для GPU подключаются вместе со средой выполнения при запуске сеанса, а сама среда выполнения размещает RPC-сервер для libc. Конечная точка QPU оказывается тем же самым кольцевым шаблоном «устройство-хост», который уже использует libc, где в качестве узла выступает FPGA. Каждая математическая функция, поддерживаемая целевой платформой и транслируемая из Python в libm, в нашем тесте на AMD Instinct MI210 дает результаты, совпадающие с результатами хоста, а функции на C вызывают sin() и printf() изнутри резидентного ядра (printf проходит через хост и используется для отладки).⁴ На пути к карте вызов sin() из C оставался в пределах 1 ulp от результата хоста на каждом проходе, и каждая строка printf доходила до места назначения.³
GPU и CPU, одна библиотека
Одна и та же библиотека собирается для GPU AMD Instinct и нативно для ядер CPU, а функция перемещается между ними путем указания другого устройства.
Рисунок 6: Одна библиотека, множество клиентов. Python, C, регионы OpenMP, резидентные рабочие процессы и цепочки ядер — все это сводится к вызовам библиотеки среды выполнения устройства, которая собрана для GPU AMD Instinct и ядер CPU. Библиотеки LLVM libc и libm располагаются рядом с ней. Цифрами отмечены четыре способа размещения функции: ① встраивание (inline), ② резидентный рабочий процесс, ③ внешний вызов и ④ цепочка ядер.
Что мы измеряли
Результаты в этом разделе представляют собой время кругового прохождения сигнала (round-trip) до устройства U55C: каждый цикл начинается, когда запрос поступает на высокопроизводительную вычислительную карту AMD Alveo™ U55C, и заканчивается, когда карта получает ответ. Таким образом, они охватывают связующую карту, шину PCIe и ускоритель, но не систему управления или кабель к ней. Все показатели циклов — это время кругового прохождения в замкнутом контуре, один запрос в процессе выполнения, более 3 x 10⁶ циклов на конфигурацию. Время измеряется по 250 МГц тактовому сигналу связующей карты от границы до границы, с учетом всех гарантий упорядочивания и проверки. Каждый потребитель работает с настройками по умолчанию, установленными производителем, и отвечает с помощью встроенной функции эхо среды выполнения.²
Увеличение изображения
Рисунок 7: Задержка кругового прохождения с 64-байтовыми кадрами на хосте AMD EPYC 7282 (вверху) и на второй платформе, хосте AMD EPYC 9755 (внизу). Столбцы показывают индивидуально зарегистрированные циклы с разрешением тактового сигнала 4 нс. На V80 в цикле находится только логика обмена. На MI355X значения p50 и p90 попадают в один и тот же интервал гистограммы, поэтому две линии совпадают.²,⁵
Потребитель (64-байтовые кадры)
p50
p90
Вычислительный ускоритель AMD Alveo™ V80
2.428 мкс
2.492 мкс
CPU AMD EPYC™ 7282, одно ядро
2.172 мкс
2.268 мкс
GPU AMD Instinct™ MI210
3.708 мкс
3.804 мкс
CPU AMD EPYC™ 9755, одно ядро (вторая платформа⁵)
1.772 мкс
1.820 мкс
GPU AMD Instinct™ MI355X (вторая платформа⁵)
3.036 мкс
3.036 мкс
Все пять показателей очень близки: у каждого потребителя 90% циклов завершаются в пределах 0.10 мкс от медианы. Для такой небольшой функции одно ядро CPU отвечает быстрее, чем GPU; GPU оправдывает свое применение, когда функция представляет собой реальное вычисление.
Гистограммы на рисунке 7 показывают несколько резких пиков, потому что в этих запусках управляющий трафик имитируется на собственной FPGA связующей карты, на той же частоте, по которой он измеряется, и каждый запрос уходит в момент получения предыдущего ответа, поэтому каждый цикл начинается в одной и той же точке цикла опроса потребителя; Qblox Cluster работает позже в этой статье, через кабель от независимого тактового генератора, распределяясь более плавно.
Результаты переносятся на вторую, более новую платформу: хост AMD EPYC™ 9755 с GPU AMD Instinct MI355X и той же связующей картой. При настройках по умолчанию MI355X отвечает за 3.036 мкс при 64 байтах (как p50, так и p90), что на 0.67 мкс быстрее, чем MI210; одно ядро EPYC™ 9755 отвечает за 1.772 мкс (p90 1.820 мкс). V80 не входил в состав этой платформы.⁵
Увеличение изображения
Qblox Cluster встречает AMD
От пар к ячеистой сети
Заключение
Сноски












