Разработка и модификация MAC-планировщиков в srsRAN 4G

Инженерный курс по изучению архитектуры srsRAN 4G на уровне исходного кода C++ и созданию собственных алгоритмов MAC-планирования. Вы освоите ZMQ-симуляции, профилирование производительности, работу с SDR USRP B200 и подготовку данных для научных публикаций.

1. Архитектура srsRAN 4G и запуск базовой ZMQ-симуляции

Приветствую на курсе. Наша итоговая цель — научиться модифицировать исходный код MAC-планировщиков в srsRAN 4G, проводить эксперименты и анализировать метрики сети. Но прежде чем писать свой алгоритм BestCQI или профилировать Proportional Fair, нам нужен надежный, воспроизводимый и легко отлаживаемый испытательный стенд.

Работа с реальным SDR-оборудованием (например, USRP B200) вносит физические переменные: радиопомехи, затухание сигнала, аппаратные задержки. Для разработки логики планировщика на начальном этапе это лишний шум. Поэтому мы начнем с ZeroMQ (ZMQ) — библиотеки асинхронного обмена сообщениями, которая в srsRAN используется для симуляции радиоэфира на уровне I/Q-сэмплов.

Архитектура srsRAN 4G: где живет планировщик

Сеть LTE концептуально делится на три крупных узла:

  • EPC (Evolved Packet Core) — ядро сети. Отвечает за аутентификацию, маршрутизацию IP-пакетов и управление сессиями.
  • eNodeB (Evolved Node B) — базовая станция. Именно здесь происходит вся магия радиодоступа и распределения ресурсов.
  • UE (User Equipment) — абонентское устройство (смартфон, модем).
  • Внутри eNodeB реализован стек протоколов радиоинтерфейса. Пакеты данных (IP) приходят из ядра сети и спускаются вниз по стеку: * PDCP (Packet Data Convergence Protocol) — сжатие заголовков и шифрование. * RLC (Radio Link Control) — сегментация пакетов и обеспечение надежной доставки (ARQ). * MAC (Medium Access Control) — мультиплексирование, гибридный автоматический запрос повтора (HARQ) и, самое главное для нас, планирование ресурсов (Scheduling). * PHY (Physical Layer) — кодирование, модуляция и формирование OFDM-символов.

    !Схема архитектуры сети LTE и стека протоколов eNodeB

    Планировщик MAC (MAC Scheduler) — это «мозг» базовой станции. Каждые 1 миллисекунду (один Transmission Time Interval, TTI) он должен решить: какому пользователю (UE) выделить частотные ресурсы (Resource Blocks, RB), какую схему модуляции и кодирования (MCS) применить, и сколько данных передать.

    Концепция виртуального радиоэфира через ZeroMQ

    В классической схеме уровень PHY передает цифровые I/Q-сэмплы на SDR-плату, которая преобразует их в аналоговый радиосигнал. В ZMQ-симуляции уровень PHY отправляет эти же I/Q-сэмплы через локальные TCP/IPC сокеты напрямую в процесс UE.

    Объем данных, передаваемых между процессами, огромен. Его можно оценить по формуле:

    Где — битрейт (бит/с), — частота дискретизации (например, 23.04 МГц для полосы LTE 20 МГц), — разрядность одного сэмпла (обычно 16 бит), а учитывает наличие синфазной (I) и квадратурной (Q) компонент.

    При МГц мы получаем Мбит/с в одну сторону только для одного антенного порта. Поэтому ZMQ-симуляция требует высокой производительности CPU и памяти.

    Сборка srsRAN 4G с поддержкой ZMQ

    Для начала установим зависимости. На Ubuntu нам понадобятся библиотеки разработчика ZeroMQ:

    Теперь клонируем репозиторий и собираем проект. Ключевой момент — убедиться, что CMake нашел библиотеку ZMQ.

    Внимательно изучите вывод cmake. Вы должны увидеть строки, подтверждающие успешный поиск ZeroMQ: > -- FINDING ZEROMQ. > -- Found libZEROMQ: /usr/include, /usr/lib/x86_64-linux-gnu/libzmq.so

    Если библиотека найдена, запускаем компиляцию:

    Изоляция сети: зачем нужны Network Namespaces

    Здесь кроется главный инженерный подвох запуска всей сети на одной Linux-машине.

    Когда запускается srsepc, он создает виртуальный сетевой интерфейс srs_spgw_sgi (обычно с IP 172.16.0.1). Когда подключается srsue, он создает свой интерфейс tun_srsue и получает IP от ядра (например, 172.16.0.2).

    Если оба интерфейса находятся в одном сетевом пространстве хоста, ядро Linux увидит, что пакет от 172.16.0.1 к 172.16.0.2 можно передать напрямую через внутреннюю таблицу маршрутизации (loopback). Трафик не пойдет через наши процессы srsepc -> srsenb -> srsue. Радиоэфир останется пустым, а планировщик MAC не получит данных для распределения.

    Чтобы заставить трафик идти через стек LTE, мы поместим UE в отдельное сетевое пространство имен (Network Namespace, netns).

    Создадим namespace с именем ue1:

    Запуск базовой симуляции

    Нам понадобятся три отдельных окна терминала. Мы будем использовать конфигурационные файлы по умолчанию, которые уже настроены на использование ZMQ.

    Шаг 1: Запуск ядра сети (EPC)

    В первом терминале запускаем ядро. Оно поднимет базу данных абонентов (HSS), шлюзы (SGW/PGW) и узел управления мобильностью (MME).

    Вывод покажет, что EPC слушает подключения от eNodeB на порту S1-MME (SCTP 36412).

    Шаг 2: Запуск базовой станции (eNodeB)

    Во втором терминале запускаем eNodeB. Мы явно указываем использовать конфигурацию для ZMQ.

    Здесь tx_port и rx_port — это TCP-сокеты, через которые базовая станция будет «излучать» и «слушать» радиоэфир. После запуска eNodeB подключится к EPC (вы увидите сообщение S1 Setup Request в терминале EPC).

    Шаг 3: Запуск абонентского устройства (UE)

    В третьем терминале мы запускаем UE, но делаем это внутри созданного ранее namespace ue1 с помощью утилиты ip netns exec.

    Обратите внимание на порты: tx_port у UE совпадает с rx_port у eNodeB, и наоборот. Это наш виртуальный радиоканал.

    В терминале UE вы увидите процесс синхронизации (Cell Search), декодирование системной информации (MIB/SIB), процедуру случайного доступа (RACH) и, наконец, успешное подключение (RRC Connected). UE получит IP-адрес, например, 172.16.0.2.

    Проверка прохождения трафика

    Теперь проверим, что данные действительно идут через MAC-уровень. Откроем четвертый терминал (на хост-машине, вне namespace) и запустим пинг до UE:

    Пинг должен успешно проходить. Задержка (latency) в ZMQ-симуляции обычно составляет 15-30 мс, что соответствует реальным показателям LTE.

    Если вы посмотрите в терминал srsenb, то при нажатии клавиши t (включение метрик) вы увидите таблицу с текущим throughput (пропускной способностью) для downlink (DL) и uplink (UL). Пока идет только ICMP-трафик от пинга, значения будут небольшими (единицы килобит).

    Чтобы нагрузить планировщик, запустим iperf3. В терминале хоста (EPC) запустим сервер:

    А в терминале UE (внутри namespace) запустим клиент:

    Теперь в консоли srsenb (по клавише t) вы увидите, как MAC-планировщик выделяет ресурсные блоки (PRB) и выбирает высокие индексы MCS (например, 28) для прокачки мегабит данных.

    Мы успешно развернули изолированную лабораторию. В следующей статье мы откроем исходный код srsenb/src/mac/scheduler.cc, разберем call flow от получения данных из RLC до формирования MAC PDU, и найдем точки входа, где принимаются решения о распределении Resource Blocks.

    2. Настройка мульти-пользовательской среды и анализ кода MAC-планировщиков

    Настройка мульти-пользовательской среды и анализ кода MAC-планировщиков

    В прошлой статье мы успешно запустили изолированную сеть с одним абонентским устройством (UE) поверх ZeroMQ. Однако планировщик ресурсов (MAC Scheduler) раскрывает свой потенциал только в условиях конкуренции. Чтобы анализировать алгоритмы Round Robin (RR) или Proportional Fair (PF), нам нужно создать мульти-пользовательскую среду, где базовая станция вынуждена принимать решения о разделении ограниченного спектра.

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

    Масштабирование ZMQ-симуляции для нескольких UE

    Главная сложность запуска нескольких UE на одной машине — изоляция сетевого трафика и маршрутизация I/Q-сэмплов.

    В базовой конфигурации ZMQ-сокеты srsRAN работают в режиме «точка-точка» (Point-to-Point). Базовая станция слушает порт 2000 и пишет в 2001, а UE делает наоборот. Если мы просто запустим второе UE, оно попытается подключиться к тем же портам, что вызовет конфликт или перезапись данных в буфере.

    Для полноценной мульти-пользовательской симуляции в srsRAN используется промежуточный ZMQ-брокер (часто реализуемый через GNU Radio), который работает как виртуальный радиоэфир: он принимает I/Q-сэмплы от eNodeB и рассылает их всем подключенным UE (Downlink), а также суммирует сигналы от всех UE и передает их на eNodeB (Uplink).

    Сетевая изоляция достигается созданием дополнительных пространств имен (Network Namespaces). Для второго устройства мы создаем ue2:

    После настройки брокера и запуска srsue внутри ue2, ядро сети (EPC) выдаст второму устройству новый IP-адрес, например, 172.16.0.3. Теперь мы можем запустить два параллельных потока iperf3 от EPC к 172.16.0.2 и 172.16.0.3, создав конкуренцию за Resource Blocks (PRB).

    Архитектура планировщика: от 4G к 5G

    Вы упоминали файлы scheduler_policy.h, scheduler_time_rr.cpp и scheduler_time_pf.cpp. Здесь важно сделать архитектурную ремарку уровня Senior.

    Эти конкретные файлы принадлежат кодовой базе srsRAN_Project — новой архитектуре, написанной с нуля для 5G (O-RAN CU/DU). В ней используется паттерн Policy Factory, где алгоритмы планирования вынесены в отдельные классы с четким интерфейсом.

    В классическом srsRAN 4G, который мы сейчас изучаем, архитектура более монолитна. Основная логика живет в файле srsenb/src/mac/scheduler.cc, а математика политик — в scheduler_metric.cc. Тем не менее, концептуальный Call Flow (поток вызовов) в обеих системах идентичен. Понимание монолита 4G делает переход к модульному 5G тривиальной задачей.

    !Схема Call Flow MAC-планировщика: от прерывания PHY до выдачи грантов

    Call Flow: как принимается решение

    Каждую 1 миллисекунду (один TTI) уровень PHY генерирует прерывание, которое запускает цепочку вызовов в MAC:

  • mac::tti_clock() — глобальный таймер MAC-уровня.
  • scheduler::tti_clock() — передача управления планировщику.
  • scheduler::schedule_dl() — начало планирования Downlink.
  • Расчет метрик — для каждого активного UE (RNTI) вызывается функция расчета приоритета (метрики) на основе текущей политики (RR или PF).
  • Сортировка — пользователи выстраиваются в очередь по убыванию метрики.
  • Аллокация PRB — планировщик идет по отсортированному списку и выделяет доступные ресурсные блоки, пока они не закончатся или пока не опустеют буферы данных (RLC Buffer Status).
  • Разбор кода: Round Robin vs Proportional Fair

    Давайте заглянем в логику расчета метрик. В srsRAN 4G за это отвечает класс scheduler_metric.

    Round Robin (RR)

    Алгоритм Round Robin не смотрит на качество радиоканала (CQI). Его цель — дать всем равное время эфира.

    При RR, если у UE1 отличный сигнал (MCS 28), а у UE2 плохой (MCS 4), они получат одинаковое количество PRB. В результате UE1 скачает 10 Мбит/с, а UE2 — 1 Мбит/с. Общая пропускная способность соты (Cell Throughput) сильно просядет из-за UE2.

    Proportional Fair (PF)

    PF пытается найти баланс между максимальной пропускной способностью соты и справедливостью. Он использует формулу:

    Где — итоговая метрика приоритета, — мгновенно доступная скорость (зависит от текущего CQI и MCS), а — историческая средняя скорость этого UE за окно времени.

    Если UE долго не получало данные, его падает, и дробь растет — планировщик вынужден дать ему ресурсы. Если у UE отличный сигнал, его велико, и оно тоже получает высокий приоритет.

    Практическая задача: интеграция собственного лога

    Чтобы научиться модифицировать код, начнем с малого — добавим профилирование аллокации. Откройте файл srsenb/src/mac/scheduler.cc, найдите конец функции schedule_dl() (после цикла аллокации) и добавьте вывод в лог:

    После изменения кода необходимо пересобрать eNodeB: ``bash cd build make -jx_iinJ\frac{1}{n}1.0$ (идеальная справедливость, все получают поровну).

    !Интерактивный калькулятор Индекса справедливости Джейна

    Рекомендации по визуализации результатов

    При подготовке графиков для статьи используйте следующие форматы:

  • CDF (Cumulative Distribution Function) пропускной способности UE. На оси X — Throughput (Мбит/с), на оси Y — вероятность. Этот график идеально показывает, как планировщик влияет на 10% худших пользователей (Cell Edge UEs).
  • Scatter Plot: Throughput vs Distance (или CQI). Показывает деградацию скорости при ухудшении сигнала для разных алгоритмов.
  • Bar Chart: Cell Throughput vs Jain's Fairness Index. Классическая демонстрация trade-off. Столбики показывают суммарную скорость, а линия поверх них — индекс Джейна.
  • В следующей статье мы напишем с нуля собственный алгоритм BestCQI, интегрируем его в кодовую базу srsRAN и используем утилиту perf` для поиска узких мест (bottlenecks) в нашем C++ коде при нагрузке в 100 виртуальных UE.