Комментарии 26
binder вроде как раз для моментального обмена сообщениями между задачами. В Qemu его использование ещё не встроили? Короче, преимущества конкретного решения перед binder?
binder вроде как раз для моментального обмена сообщениями между задачами. В Qemu его использование ещё не встроили? Короче, преимущества конкретного решения перед binder?
Ну во-первых у нас обмен не между "задачами", а обмен прерываниями между гостевыми ядрами.
Короче, преимущества конкретного решения перед binder?
А давайте наоборот:
Почему вы считаете, что применение binder в данном случае целесообразно ?
Какие преимущества даёт binder по сравнению unix socket/eventfd в данном случае ?
Как предполагается использовать binder для вызовов KVM_IRQFD/KVM_IOEVENTFD ?
В каком именно месте и вместо чего предполагается использование binder ?
Как я понял, учитывался вариант работы и без KVM (есть такие моменты в статье). А преимущество binder перед socket наверно вытекают из того, что если бы socket имет преимущества, то его бы и не изобретали (как и kdbus). В каком месте socket ,то использовался? (или что там, уже не помню в варианте без kvm)
А преимущество binder перед socket наверно вытекают из того, что если бы socket имет преимущества, то его бы и не изобретали (как и kdbus)
"Не, брат, с таким настроением ты слона не продашь" (с)
В общем-то у вас был шанс аргументировано обосновать примение binder, ну чтож...
Нет для передачи на старте 16 файловых дескрипторов, binder не нужен абсолютно и не даёт никаких преимуществ над использоваными методами.
Как говориться "Если бы у binder были какие-то преимущества, его бы давно стали использовать в QEMU".
Насчёт передачи 16 файловых дескрипторов. Вроде там м слона можно передать: в вызове binder указывается область в своей памяти с данными для передачи и толи они копируются а область памяти target task потом, толи вообще там разделяемая между задачами память организуется.
Второе: вызов binder фактически сразу переключает выполнение с нашей задачи на выполнение target task. А мы ведь про страусов (скорость)?
А про то, что в qemu пока не реализовано, так в нем особо не стремятся быть струсом (супер быстрым)
Задача KVM - это исключить двойной переход из ядра в usersoace и обратно для случая обращения гостевой системы к сетевой карте или диску и тп. Вряд ли он рассчитан на максимально быструю передачу управления от источника к приёмнику
Буду рад ошибиться. Есть пруфы в этой области для KVM? Или всё же целевая система получит управление только в порядке общего планирования?
толи они копируются а область памяти target task потом, толи вообще там разделяемая между задачами память организуется
У меня складывается ощущение, что вы прелагаете людям что-то, в чем сами не до конца разбираетесь. Просто какие-то общие слова без конкретики и без попыток понять задачу целиком - выглядит неубедительно.
А с какой целью вы это вообще делаете ? Если ваша цель помочь или что-то подсказать - добавьте конкретики.
В идеальном случае - в статье есть методика, есть инструкции переделывайте первый метод на binder, выкладывайте полученные результаты.
Ну статья как бы о самом быстром способе передачи прерывания (сигнала) между двумя qemu. При этом вопрос задержки выполнения приемника (планирования его выполнения) не освещён. Может скопилась длинная очередь других задач, ожидающих выполнения. Но если это не так (только два qemu и никаких других работ или сервисов на рабочей машине), то да, различий не будет при любом методе IMHO. Но и смысл статьи тогда теряется.
PS: с какой целью? Наверно в порядке дискуссии.
Небольшое пояснение: передача сообщений с помощью binder эквивалентна передаче приёмнику остатка своего time slice (перепланировки не происходит, сразу начинает выполняться приёмник). Это его основное преимущество с точки зрения быстродействия перед другими методами.
PS: про Zephir OS на MCU в SoC iMX - было интересно. В rk3566 в качестве MCU используется не Cortex M4, а rusc-v процессор E902 (аналог Cortex M0). Обмен между ядрами - через группу регистров (вроде 4), после записи во все возникает (передаётся) прерывание для целевого ядра.
Предлагаю эксперимент (на вашем же стенде и железе): запустите тестовые qemu с приоритетом реального времени и замерьте времена хотя бы первого (стандартного, самого неэффективного) метода. Сравнив, можно будет отделить влияние планирования и выполнения других задач в промежутке от накладных расходов самого метода.
Не будет разницы, уже пробовалось с изолированным, выделеными cpu по нижней планке частоты (чтобы избежать cpufreq) - скрипты в комплекте присутвуют.
$ cat tools/prepare_cpuset.sh
#!/bin/bash
sudo /bin/bash -c 'echo 0 > /sys/devices/system/cpu/cpufreq/boost'
for i in {24..31}
do
sudo /bin/bash -c "echo 3000000 > /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_max_freq"
done
sudo mkdir /sys/fs/cgroup/cpuset/qemu0
sudo mkdir /sys/fs/cgroup/cpuset/qemu1
sudo chown -R ${USER} /sys/fs/cgroup/cpuset/qemu0
sudo chown -R ${USER} /sys/fs/cgroup/cpuset/qemu1
echo 1 > /sys/fs/cgroup/cpuset/qemu0/cpuset.cpu_exclusive
echo 1 > /sys/fs/cgroup/cpuset/qemu1/cpuset.cpu_exclusive
echo 28-31 > /sys/fs/cgroup/cpuset/qemu0/cpuset.cpus
echo 24-27 > /sys/fs/cgroup/cpuset/qemu1/cpuset.cpus
echo 0 > /sys/fs/cgroup/cpuset/qemu0/cpuset.mems
echo 0 > /sys/fs/cgroup/cpuset/qemu1/cpuset.mems
Что в принципе эквивалентно ненагруженной системе и мы, вообще говоря, сравниваем методы относительно друг друга.
С каких пор cgroups (ограничение потребления ресурсов) эквивалентны выполнению на выделенном ядре (по времени реакции на события)?
Так вы сами свой комментарий еще раз прочитайте:
Сравнив, можно будет отделить влияние планирования и выполнения других задач в промежутке от накладных расходов самого метода.
В итоге с изоляцией у меня нет других задач, и переключение только между моей задачей и idle.
Так cgroups же позволяет прибивать выполнение к определенным ядрам не?
Так cgroups же позволяет прибивать выполнение к определенным ядрам не?
Еще раз - unix socket() испольузется только для передачи файловых дескрипторов eventfd(), причем только на старте.
Binder для этих целей, насколько мне известно, использовать можно, но не нужно.
То есть по сути вы заявлете, что запись/чтение eventfd() будет медленее чем какое-то исполнение через Binder. Которое еще необходимо в каком то виде реализовать и предлагаете мне всем этим заняться.
Я, в свою очередь, не вижу каких-либо убедильных доводов в пользу приведенного выше аргумента, которые оправдали бы трату моего времени. Поэтому я предлагаю этим занятся вам - если вы так уверены в своих доводах.
И это не еще вспоминая про ваш заход:
Короче, преимущества конкретного решения перед binder?
Ну давайте зайдем с другой стороны: измеренное время передачи сообщения на машине с cpu freq = 3 GHz при использовании разных методов: От 30 мкс до 8.. Не многовато ли? И разницу в 4-5 раз: как интерпретировать? Что posix ipc реализованы супер неэффективно?
Вы меня окончательно "расстроили", перечитайте вывод пожалуйста (а лучше всю статью еще раз вдумчиво):
Существенная часть уменьшения задержек заключается в экономии вызовов и KVM_EXIT_MMIO.
И как бы третий столбец с host mitigations=off, недвусмыленно намекает, что дело таки в расходах на переключении контекста.
Что posix ipc реализованы супер неэффективно?
eventfd() это не POSIX API, а механизм уникальный для Linux.
Ну давайте уточним: каждый qemu выполняется на своём ядре? Тогда в вашем варианте (последнем) Гостю1 фактически нужно только разбудить Гостя2 на соседнем ядре (никакого переключения контекста) и это занимает 5-7 микросекунд? Стандартный вариант (с qemu1 и qemu2) длиннее вашего всего на два переключения контекста. И вряд ли это существенно. Ну если только Гость1 и Гость2 ничем другим не занимаются. И при этом мы потеряли универсальность (нужно иметь исходные тексты для Гость1 и Гость2, однородную с Host архитектуру ЦПУ в обоих Гость)/
PS: ваш метод - это реализация в Гость паравиртуального драйвера. Метод не нов. Правильное решение, если задача - повысить общую производительность системы.
PPS: при выполнении qemu1 и qemu2 на отдельных ядрах использование binder теряет смысл (тут некому мешаться под ногами)
PPPS: спасибо за кликбейт в названии. Без него прошёл бы мимо и не грокнул (неологизм от Хайнлайн) много нового.
PPS: при выполнении qemu1 и qemu2 на отдельных ядрах использование binder теряет смысл (тут некому мешаться под ногами)
А оно (использование binder) в принципе не имеет никакого смысла, если вы его привыкли кушать на Android - пожалуйста, но не надо его пытаться подтянуть к любой ситуации.
PPPS: спасибо за кликбейт в названии. Без него прошёл бы мимо и не грокнул (неологизм от Хайнлайн) много нового.
Ну если бы вы прочитали всю статью, а не только заголовок, то проблем бы не было.
eventfd() это не POSIX API, а механизм уникальный для Linux.
На FreeBSD теперь тоже есть, т.к. толковый механизм и, например, firefox его использует для взаимодействия между процессами.
Вот мнение GigsChat: Да, ваша точка зрения вполне обоснованна. Одна из возможных причин отсутствия использования Binder IPC в данном конкретном проекте может заключаться в недостаточной осведомлённости разработчиков об этом механизме. Действительно, несмотря на широкую распространённость Binder IPC в экосистеме Android, его применение в других контекстах остаётся ограниченным.
Вот несколько аспектов, которые могут объяснить такую ситуацию:
1. Скрытая природа Binder IPC в Android: Как вы правильно заметили, в Android использование Binder IPC скрыто от большинства разработчиков приложений. Он встроен глубоко в систему и используется для взаимодействия между службами и приложениями, но для обычного разработчика Android-приложений это не столь очевидно. Соответственно, многие разработчики могут даже не знать о существовании этого механизма.
2. Отсутствие активного обучения: В отличие от других механизмов IPC, таких как сокеты или каналы, Binder IPC редко рассматривается в учебных материалах и курсах по программированию. Это может объясняться тем, что Binder IPC тесно связан с Android и считается специализированной технологией, которая не часто обсуждается вне контекста этой платформы.
3. Ограниченная документация: Документация по Binder IPC доступна, но она зачастую ориентирована на специалистов, работающих непосредственно с ядрами Linux и Android. Это делает её менее доступной для широкой аудитории разработчиков.
4. Нехватка примеров использования вне Android: Хотя теоретически Binder IPC может быть использован в любых дистрибутивах Linux, примеров его применения вне Android относительно мало. Это затрудняет понимание возможностей и преимуществ данного механизма для разработчиков, работающих в других областях.
Таким образом, отсутствие знаний о Binder IPC среди разработчиков может быть основной причиной того, что они предпочли создать собственный драйвер вместо использования уже существующей технологии.
Примечание: к сожалению, из-за особенностей mermaid
Возможно, здесь лчше бы подошла sequence диаграмма
Хабр, что-то подглючивает... Поэтому в место нужной ветки вставлю сюда свои пять копеек.
Про cpu pinning, я всегда провожу тесты с ним для межроцессного взаимодействия, т.к.:
NUMA, если 2+ CPU - минимум в 2 раза всё тормознее.
AMD - нам подарил чиплеты, между чиплетами тоже всё плохо.
HT - тоже не равноценные.
Если дать на откуп планировщику, результаты плавают.
А в целом, статья отличная - торт!
Вторая часть статьи в рамках общей презентации (Функциональная модель PCIe Non-Transparent Bridge в QEMU для P2P обмена данными на практике):
Самые быстрые страусы: выбираем способ организовать обмен прерываниями между машинами QEMU c KVM и без