Вопрос или проблема
У меня есть процессор ARM Cortex-A9 с двумя ядрами, работающим на частоте 800 МГц. На ARM процессоре выполняется встроенный Linux на базе Yocto с ядром 5.15 (скоро будет обновлено до 6.6).
Когда я передаю данные через TCP с помощью iperf3 -c <IP> --zerocopy
, максимальная скорость передачи данных составляет 760 Мбит/с. Одно ядро полностью используется (100%) для некоторых функций в пространстве ядра в инструменте iperf3. Я предполагаю, что для генерации TCP-пакетов необходимо это время.
Существует ли какая-либо конфигурация ядра, позволяющая включить многопоточность и использовать оба ядра для TCP-стека?
Ответ или решение
Параллелизация TCP-стека в embedded Linux на ARM Cortex-A9
При передаче данных через TCP на вашем двухъядерном процессоре ARM Cortex-A9 с частотой 800 МГц и использованием Embedded Linux на базе Yocto с ядром 5.15, вы столкнулись с ограничением скорости передачи на уровне 760 Мбит/с, при этом один из ядер полностью загружен. Решение этой проблемы может потребовать ряда шагов для оптимизации параллелизации TCP-стека.
1. Понимание проблемы
При передаче данных с использованием протокола TCP, нагрузка на одно ядро может возникать из-за последовательной обработки пакетов и ограничений, связанных с архитектурой TCP/IP. Ваша проблема заключается в том, что одно ядро обрабатывает весь трафик, что не позволяет использовать ресурсы второго ядра.
2. Конфигурация ядра
Для начала, нужно проверить настройки вашего ядра Linux:
-
Убедитесь, что поддержка SMP (Symmetric Multi-Processing) активирована в конфигурации ядра. Это позволит ядру использовать оба ядра вашего процессора. Для проверки этого выполните команду:
grep CONFIG_SMP /boot/config-$(uname -r)
Если опция неактивна, обновите конфигурацию ядра и соберите его заново.
3. Обновление ядра
Планируемое обновление вашей системы до ядра 6.6 может принести дополнительные возможности для оптимизации. Более новые версии ядра часто имеют улучшенные механизмы управления потоками и могут лучше использовать многопоточность.
4. Использование многоядерной модели TCP
В Linux существуют улучшенные механизмы для распределения нагрузки между ядрами. Для активного использования обоих ядер рекомендуется настроить балансировщик нагрузки TCP. Это можно сделать с помощью:
SO_REUSEPORT
: Этот сокетный параметр позволяет нескольким сокетам прослушивать один и тот же IP-адрес и порт, распределяя входящие подключения между доступными потоками. Чтобы использоватьSO_REUSEPORT
, необходимо на серверной стороне iperf3 или вашего приложения настроить сетевые сокеты.
Пример использования в программном коде на C:
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
5. Настройка сетевых интерфейсов
Иногда проблема заключается в каналах связи. Убедитесь, что сетевые адаптеры правильно настроены. Рассмотрите возможность использования «отделения» потоков TCP по разным ядрам, используя механизмы tc
и правила маршрутизации. Это позволит управлять распределением нагрузки на уровне ядер.
6. Кэширование и обработка данных
Параллелизация TCP-стека может быть достигнута путем оптимизации обработки и кэширования данных. Посмотрите на механизмы, такие как zero-copy
, которые вы уже используете, чтобы минимизировать накладные расходы на переключение контекста.
7. Мониторинг и анализ
Используйте инструменты мониторинга, такие как htop
, perf
или ftrace
, чтобы глубже понять, где возникают узкие места. Это поможет вам определить, какие функции занимают больше всего времени и требуют оптимизации.
Заключение
Обеспечение параллелизации TCP-стека на вашем ARM Cortex-A9 возможно через правильную настройку ядра, использование современных возможностей многопоточности, настройку сетевых интерфейсов и оптимизацию приложений. Следует помнить, что тестирование и всесторонний анализ системы помогут выявить узкие места и помогут вам в использовании обоих ядер процессора для достижения максимальной скорости передачи данных.
Не забудьте после внесения изменений протестировать производительность с помощью iperf3
для уверенности в улучшении.