Каков идеальный и самый быстрый способ связи между ядром и пространством пользователя? - PullRequest
8 голосов
/ 03 июня 2009

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

  • системные вызовы

  • IOCTLs

  • / proc & / sys

  • NetLink

Я хочу узнать

  • Если я пропустил какой-либо другой интерфейс?

  • Какой из них является самым быстрым способом обмена большими объемами данных? (и если есть какой-либо документ / почта / объяснение, подтверждающее такую ​​претензию, на которую я могу сослаться)

  • Какой из них рекомендуется способ общения? (Я думаю, что это netlink, но все равно хотелось бы услышать мнения)

Ответы [ 6 ]

7 голосов
/ 03 июня 2009

Самый быстрый способ обмена огромным количеством данных - это отображение памяти. Вызов mmap может использоваться в файле устройства, и соответствующий драйвер ядра может затем принять решение о сопоставлении памяти ядра с адресным пространством пользователя. Хорошим примером этого являются драйверы Video For Linux, и я предполагаю, что драйвер кадрового буфера работает так же. Для хорошего объяснения того, как работает драйвер V4L2, у вас есть:

Вы не можете превзойти отображение памяти для большого объема данных, потому что нет никакой операции, подобной операции memcopy, физическая базовая память эффективно разделяется между ядром и пространством пользователя. Конечно, как и во всем механизме совместной памяти, вам необходимо обеспечить некоторую синхронизацию, чтобы ядро ​​и пользовательское пространство не думали, что они одновременно владеют.

6 голосов
/ 03 июня 2009

Совместно используемая память между ядром и областью использования выполнима.

http://kerneltrap.org/node/14326

Для инструкций / примеров.

Вы также можете использовать именованный канал , который довольно быстр.

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

ядро ​​Linux / proc FIFO / pipe

Может также помочь

удачи

5 голосов
/ 07 июля 2009

Вы также можете рассмотреть реле (ранее relayfs):

"По сути, relayfs - это просто набор буферов ядра для каждого процессора, которые могут быть эффективно записаны из кода ядра. Эти буферы представлены в виде файлов, которые можно mmap'ить и непосредственно читать из пространства пользователя. Цель этого установка должна обеспечить самый простой возможный механизм, позволяющий регистрировать потенциально большие объемы данных в ядре и «ретранслировать» в пространство пользователя. "

http://relayfs.sourceforge.net/

2 голосов
/ 03 июня 2009

Очевидно, что вы можете создавать общую память с помощью copy_from_user и т. Д., Вы можете легко настроить драйвер символьного устройства, в основном все, что вам нужно сделать, это создать структуры file_operation, но это далеко не самый быстрый способ. У меня нет тестов, но системные вызовы на современных системах должны быть самыми быстрыми. Я считаю, что это то, что было наиболее оптимизировано для. Раньше считалось, что для перехода от ядра user -> нужно было создать прерывание, которое затем попадало бы в таблицу прерываний (массив), затем определяло местонахождение прерывания прерывания (0x80) и затем переходило в режим ядра. Это было очень медленно, а затем появилась инструкция .sysenter, которая в основном делает этот процесс очень быстрым. Не вдаваясь в подробности, .sysenter считывает из реестра CS: EIP сразу, и изменения происходят довольно быстро. Совместно используемая память, напротив, требует записи в память и чтения из памяти, что бесконечно дороже, чем чтение из регистра.

1 голос
/ 27 июня 2018

Что касается разделяемой памяти, я обнаружил, что даже с NUMA два потока, работающие на двух разных ядрах, обмениваются данными через разделяемую память, все еще требуя запись / чтение из кэша L3, который, если повезет (в одном сокете) примерно в 2 раза медленнее, чем системный вызов, а если (не на одном сокете), это примерно в 5 раз больше медленнее, чем syscall, я думаю, что аппаратный механизм syscall помог.

1 голос
/ 22 июня 2015

Вот возможная компиляция всех возможных интерфейсов, хотя в некоторых отношениях они перекрывают друг друга (например, сокет и системный вызов эффективно используют системные вызовы):

Procfs
Sysfs
Configfs
Debugfs
Sysctl
devfs (eg, Character Devices) 
TCP/UDP Sockets
Netlink Sockets 
Ioctl
Kernel System Calls
Signals
Mmap
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...