Найти в Дзене
Nervos Network

Основное обновление протокола — погружение в CKB-VM V1

Оглавление

Технический обзор новых функций CKB-VM v1 из хардфорка CKB2021.

Введение

В предыдущей статье мы дали общий обзор улучшений CKB-VM v1 и объяснили основной процесс активации и использования преимуществ этой новой среды VM. Далее мы углубимся в новшества CKB-VM v1 и более технически объясним, как эти улучшения работают и расширяют возможности разработчиков.

Расширение RISC-V B

Расширение RISC-V B — это наше первое обновление набора инструкций, на котором работает CKB-VM. Это расширение набора инструкций относительно небольшое, но оно доказывает, что этот путь обновления работает как в теории, так и на практике.

Расширение B охватывает четыре основные категории манипуляций с битами: подсчет, извлечение, вставка и замена. Всего введено 43 новых инструкции, для каждой из которых требуется только 1 цикл.

Во многих криптографических алгоритмах используются битовые операции, такие как clz, циклические сдвиги и т. д. Добавление расширенного набора команд B позволяет увеличить скорость таких вычислений не менее чем в 10 раз. Рассмотрим clz в качестве примера. Традиционно мы используем следующий алгоритм:

uint64_t clz(uint64_t n)
{
    if (n == 0) return 64;
    int c = 0;
    if (n <= 0x00000000FFFFFFFF) { c += 32; n <<= 32; };
    if (n <= 0x0000FFFFFFFFFFFF) { c += 16; n <<= 16; };
    if (n <= 0x00FFFFFFFFFFFFFF) { c += 8; n <<= 8; };
    if (n <= 0x0FFFFFFFFFFFFFFF) { c += 4; n <<= 4; };
    if (n <= 0x3FFFFFFFFFFFFFFF) { c += 2; n <<= 2; };
    if (n <= 0x7FFFFFFFFFFFFFFF) { c += 1; };
    return c;
}

В приведенном выше коде используется около 30 инструкций. Но с расширением B нам нужно провести только одну инструкцию, чтобы сделать это!

uint64_t clz(uint64_t n) {
    uint64_t rd;
    __asm__ (“clz %0, %1” : “=r”(rd) : “r”(n));
    return rd;
}

Расширение B было интегрировано в последнюю версию gcc. Чтобы скомпилировать код с расширением b, вам нужно добавить параметр -march=rv64imc_zba_zbb_zbc, например:

riscv64-unknown-elf-gcc -o /tmp/main -march=rv64imc_zba_zbb_zbc main.c

Давайте рассмотрим реальный пример, показывающий, что расширение B повышает производительность алгоритма Blake2b. Он просто заменяет функцию одной инструкцией расширения B. Первоначальная версия выглядит следующим образом:

static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
  return (w >> c) | (w << (64 – c));
}

Update it with B extension instructions:
static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
  uint64_t rd = 0;
  __asm__ (“ror %0, %1, %2” : “=r”(rd) : “r”(w), “r”(c));
  return rd;
}

Благодаря этому небольшому изменению производительность увеличилась на 15%. Nervos часто использует алгоритм Blake2b, а это означает, что это значительное улучшение нашей экосистемы.

Основные компиляторы, такие как GCC, в настоящее время недостаточно усовершенствованы, чтобы автоматически преобразовывать исходный код в инструкции расширения RISC-V B. Это означает, что разработчикам по-прежнему необходимо вручную использовать ассемблерный код для настройки производительности, как это было сделано выше. В будущем компиляторы будут иметь лучшую поддержку расширения B, а это означает, что разработчики смогут значительно повысить производительность, просто обновив свой компилятор до более новой версии.

Предварительный тест показал улучшение примерно на 10% в наборе криптографических алгоритмов, требующих больших вычислительных ресурсов.

Мы надеемся, что при добавлении дополнительных расширений в будущем криптографические примитивы, работающие в CKB-VM, получат эффективность выполнения, сравнимую с собственным выполнением. Эти типы улучшений сохранят CKB-VM в авангарде отрасли и предоставят разработчикам криптографии и разработчикам dApp больше возможностей и свободы в этом узкоспециализированном приложении, где важен каждый бит эффективности.

Слияние макро-операций (MOP)

Слияние макроопераций — это метод аппаратной оптимизации, применяемый во многих современных компьютерных микроархитектурах, при котором ряд смежных макроопераций объединяется в одну макрооперацию до или во время декодирования. Эти инструкции позже декодируются в одну объединенную инструкцию. Если вы не знакомы с MOP и хотели бы узнать больше, вы можете найти несколько полезных ссылок здесь и здесь.

Поскольку CKB-VM является абстрактным уровнем аппаратного обеспечения CPU/памяти, технология MOP может использоваться так же, как и в эквивалентном аппаратном обеспечении. Здесь мы покажем, как CKB-VM может использовать MOP для объединения нескольких инструкций в одну. Давайте сначала возьмем пример умножения. Предположим, нам нужно вычислить следующее 128-битное целочисленное значение без знака (результат) в C:

uint64_t a = 0xFFFFFFFFFFFFFFFF;
uint64_t b = 0xFFFFFFFFFFFFFFFF;
uint128_t result = a * b;

Компилятор не может обрабатывать 128-битные целые числа в одной инструкции. Затем он компилирует их в несколько инструкций, которые должны содержать следующие инструкции RISC-V:

mulhu
mul

Инструкция mulhu может обрабатывать больше 64 бита результат, в то время как инструкция mul обрабатывает меньше 64 бита. Идея MOP состоит в том, чтобы объединить инструкции mulhu/mul RISC-V в одну объединенную инструкцию. CKB-VM может реализовать эту объединенную инструкцию на ассемблере. Например, на x86-64 это реализуется двумя инструкциями x86-64:

movq
imulq

Основным преимуществом этого является то, что циклы могут быть значительно сокращены с помощью MOP. Раньше для инструкций mulhu/mul требовалось 10 (5 + 5) тактов. После того, как MOP реализован, он потребляет всего 5 циклов для одной объединенной инструкции. Это 100% прирост производительности.

Вот список всех инструкций MOP, включенных в CKB-VM v1. Отмеченные операции умножения имеют решающее значение для алгоритмов криптографии. MOP может значительно повысить производительность всех криптографических алгоритмов, работающих на CKB-VM. Мы вручную оптимизировали bls12-381 и сократили проверку с 76,6 млн циклов до 51,8 млн циклов. Вот одна реализация проделанной работы. Вы видите множество примеров инструкций mulhu/mul, появляющихся рядом. Эта оптимизация позволяет использовать MOP.

К сожалению, GCC и другие компиляторы еще не оптимизированы для инструкций MOP RISC-V. Это означает, что сегодня разработчикам по-прежнему приходится вручную упорядочивать ассемблерный код для оптимизации MOP. Однако мы знаем, что это будет исправлено в будущем, когда компиляторы начнут добавлять поддержку.

Exec Syscall

Системный вызов exec вдохновлен системным вызовом Linux exec. Системный вызов exec запускает исполняемый код, содержащийся в области данных определенной ячейки. Этот исполняемый файл запускается в том же контексте, что и текущая виртуальная машина, и заменяет ранее запущенный исполняемый файл, выполнивший вызов. Количество используемых циклов не меняется, но код, регистры и память ВМ заменяются кодом новой программы.

Системный вызов exec очень полезен для повторного использования кода в сценариях. В качестве примера возьмем скрипт блокировки. Почти каждый сценарий блокировки использует общий процесс проверки одной или нескольких криптографических подписей. Мы можем создать один общий сценарий, который выполняет только проверку подписи, включая SECP256K1, RSA, Schnorr и т. д. Этот сценарий редко требует изменений.

Разработчики, создающие сценарии блокировки, могут упростить свой процесс, используя системный вызов exec для выполнения вышеупомянутого сценария, содержащего проверку подписи. Это позволяет им удалить код проверки подписи из своего скрипта, устраняя избыточность и позволяя им сосредоточиться исключительно на логике, характерной для их децентрализованного приложения.

Мы рекомендуем разработчикам продолжать использовать этот шаблон, чтобы сделать сценарии более удобными для компоновки и совместного использования.

Сборка ARM64

CKB-VM уже имеет высокоэффективную реализацию спецификаций RISC-V на x86-64, а с хардфорком CKB2021 мы представляем реализацию сборки ARM64. Эта функция дает CKB-VM огромный прирост производительности на платформах ARM64. ARM64 — это архитектура CPU, которая используется на миллиардах устройств, таких как смартфоны и планшеты Apple и Android, устройства Raspberry Pi, ноутбуки Google Chrome и новейшая линейка настольных и портативных компьютеров Apple M1 и M2. Microsoft также тестирует версию Windows 11, работающую на ARM64. Мы считаем, что архитектура ARM64 будет становиться все более и более популярной, и мы уверены, что CKB-VM не отстанет от этой тенденции.

Другие улучшения CKB-VM

Несколько других улучшений также были сделаны за кулисами CKB-VM. Первый — ленивая инициализация во время выполнения скрипта в CKB-VM. Раньше, когда CKB-VM выполняла сценарий, первым шагом была инициализация всей памяти до нуля. Если часть памяти никогда не используется во время выполнения, неиспользуемая память остается зарезервированной, это не оптимально. Теперь при выполнении скриптов инициализация памяти откладывается. Память программы разделена на несколько фреймов, и только при первом обращении к фрейму блок памяти резервируется и инициализируется всеми нулями. В результате небольшие сценарии, не требующие больших объемов памяти, начнут выполняться быстрее и потребуют меньше памяти во время выполнения.

Еще одно улучшение — добавление «режима хаоса». При производственном использовании вся память всегда инициализируется нулем при первом использовании. Однако во время тестирования и отладки мы можем использовать режим хаоса для инициализации памяти случайными значениями вместо нуля. Этот метод создает рандомизированные синтетические сценарии, которые могут помочь в поиске определенных ошибок в сценариях, таких как доступ к неинициализированной памяти. Это серьезная проблема, которую может быть очень трудно найти в обычных условиях, но режим хаоса может помочь выявить проблему намного быстрее.

Итог

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

Некоторые из описанных нами обновлений могут быть более глубокими, этим они интересуют многих разработчиков, но от них выигрывают все разработчики и пользователи. Неважно, являетесь ли вы разработчиком низкого уровня на L1 или разработчиком EVM на L2. Неважно, являетесь ли вы пользователем нативного приложения dApp на Nervos или пользователем на периферии одного из наших партнеров по мультичейн-экосистеме. Даже пользователи, которые не понимают, что dApp, который они используют, основан на Nervos, выиграют от прочной основы и тщательной оптимизации, которые делают Nervos исключением в отрасли.