Настройка рантайма — арена файберов (Plan 149 / D233)

Программы Nova выполняют пользовательский код на лёгких файберах, которые планирует Vela (M:N-рантайм) поверх рабочих потоков. Каждому рабочему потоку принадлежит арена файберов: зарезервированная виртуальная область (страницы коммитятся лениво), разбитая на слоты фиксированного размера — по одному на конкурентный файбер. Две ручки настройки позволяют подогнать арену под конкретную нагрузку — это runtime-свойства готовой программы в стиле GOMAXPROCS, а НЕ флаги компилятора.

Ручки настройки

Что настраиваетПеременная окруженияnova.toml [runtime]По умолчаниюДиапазонАвто-коррекция
Стек на файберNOVA_FIBER_STACKfiber_stack4MB256KB256MBокругление ВВЕРХ до размера страницы
Макс. файберов / рабочий потокNOVA_FIBERS_PER_WORKERfibers_per_worker1638464262144округление ВВЕРХ до кратного 64
  • Стек на файбер — полезный стек, который получает каждый файбер (минус защитная страница 16KB). Поднимайте его для глубоко рекурсивных тел файберов; опускайте, чтобы уместить больше файберов в ту же память. Встроенный дефолт был снижен с 8MB до 4MB ради двукратной плотности файберов «из коробки».
  • Макс. файберов / рабочий поток — потолок одновременных файберов на один рабочий поток. Общая ёмкость процесса = fibers_per_worker × NOVA_MAXPROCS (по одной арене на рабочий поток).

Человекочитаемые размеры

NOVA_FIBER_STACK и fiber_stack принимают простое число байт или двоичный суффикс (без учёта регистра): KB/K = 1024, MB/M = 1024², GB/G = 1024³.

NOVA_FIBER_STACK=8MB        # 8 388 608 bytes
NOVA_FIBER_STACK=2097152    # same as "2MB"
NOVA_FIBER_STACK=512KB

NOVA_FIBERS_PER_WORKER обычно задаётся обычным целым (20000); суффиксы K/M тоже принимаются для симметрии.

Приоритет

env  >  nova.toml [runtime] (-D compile-time default)  >  builtin default

nova.toml [runtime] запекает значение в сборку как compile-time значение по умолчанию; соответствующая переменная окружения, читаемая заново при инициализации арены каждого рабочего потока, переопределяет его в рантайме. Пример:

# nova.toml — project-baked defaults
[runtime]
fiber_stack = "2MB"
fibers_per_worker  = 8192

С указанным манифестом программа поставляется с дефолтом стека 2MB. Установка NOVA_FIBER_STACK=8MB при запуске переопределяет его на 8MB без перекомпиляции.

nova build и nova bench (одиночный файл, директория и --profile) резолвят секцию [runtime] (и секцию [ffi] из Plan 115) из пакетного nova.toml точно так же, как nova test, поэтому запечённый дефолт действует независимо от того, какая команда CLI собрала бинарник. Приоритет выше не изменился — расширился лишь набор команд, которые уважают манифест.

Авто-коррекция и безопасность

Можно указать любое значение — рантайм сам его поправит:

  • Округление ВВЕРХ, без отклонения по выравниванию. Стек округляется вверх до размера страницы; число файберов — вверх до кратного 64 (NOVA_FIBERS_PER_WORKER=2000020032).
  • Ограничение вне диапазона + предупреждение. Стек ниже 256KB → прижимается к нижней границе 256KB (nova: NOVA_FIBER_STACK ... below floor — using 256KB). Максимум выше compile-time потолка (262144) → ограничивается (nova: NOVA_FIBERS_PER_WORKER ... exceeds max — clamped).
  • Мусор → предупреждение + дефолт, без падения. NOVA_FIBER_STACK=banana печатает nova: invalid NOVA_FIBER_STACK — using default 4MB и работает на дефолте.

Переполнение стека

Если файбер рекурсивно уходит глубже своего полезного стека, он чисто падает на защитной странице с подсказкой:

nova: fiber stack overflow in slot N ...
Hint: increase NOVA_FIBER_STACK (env / nova.toml [runtime].fiber_stack) or reduce recursion depth.

Бюджет памяти

Слоты резервируют виртуальное адресное пространство лениво (POSIX mmap MAP_NORESERVE; Windows VirtualAlloc MEM_RESERVE) — физическая память коммитится только под затронутые страницы. Тем не менее виртуальное резервирование равно fibers_per_worker × stack × workers. Раскрутка обеих ручек до крайностей (например, 262144 × 256MB × 16) может исчерпать пользовательское виртуальное адресное пространство; размеряйте произведение под то, что допускает хост.

Примечания

  • Стоимость битовой карты зафиксирована на compile-time потолке (262144 слотов ⇒ 32KB на арену) и не зависит от дефолта рантайма — подъём NOVA_FIBERS_PER_WORKER выше дефолта не увеличивает per-platform массивы.
  • Защитная страница (16KB) и инварианты планировщика/GC не зависят от настройки; конфиг арены читается один раз при инициализации рабочего потока.
  • На 32-битных целях арена намеренно маленькая: SLOT_COUNT_MAX = 1024, а дефолт рантайма — 64 слота (= 256MB виртуально). Внутренний литерал NOVA_FIBERS_PER_WORKER_BUILTIN исправлен с 16 на 64 — округление вверх до кратного 64 плюс пол MIN=64 и так принудительно давали 64 в рантайме, так что старое 16 (и его комментарий «64MB») было мёртвым. Дефолты 64-bit / Windows не изменились (16384).

Полный контракт — spec D233 (spec/decisions/08-runtime.md).