Хотя все приведенные выше ответы очень хороши, я думаю, нам придется обсудить, что является «самым быстрым» [и должно ли оно быть «самым быстрым» или просто «достаточно быстрым для»?]
Для БОЛЬШИХ сообщений разделяемая память, без сомнения, является очень хорошей техникой и очень полезной во многих отношениях.
Однако, если сообщения небольшие, есть недостатки, связанные с необходимостью придумывать собственный протокол передачи сообщений и метод информирования другого процесса о наличии сообщения.
Каналы и именованные каналы в этом случае намного проще использовать — они ведут себя почти как файл, вы просто записываете данные на стороне отправки и читаете данные на стороне получателя. Если отправитель что-то пишет, получатель автоматически просыпается. Если труба заполнена, отправляющая сторона блокируется. Если данных от отправителя больше нет, принимающая сторона автоматически блокируется. Это означает, что это может быть реализовано в довольно небольшом количестве строк кода с достаточно хорошей гарантией того, что оно будет работать всегда и всегда.
С другой стороны, общая память полагается на какой-то другой механизм, чтобы сообщить другому потоку, что «у вас есть пакет данных для обработки». Да, это очень быстро, если у вас есть БОЛЬШИЕ пакеты данных для копирования, но я был бы удивлен, если бы на самом деле была огромная разница с каналом. Основное преимущество заключается в том, что другой стороне не нужно копировать данные из общей памяти, но она также зависит от наличия достаточной памяти для хранения всех сообщений «в полете» или от отправителя, имеющего возможность удерживать данные. .
Я не говорю «не используйте разделяемую память», я просто говорю, что не существует такого понятия, как «одно решение, которое лучше всего решает все проблемы».
Чтобы уточнить: я бы начал с реализации простого метода с использованием канала или именованного канала [в зависимости от того, что подходит для целей] и измерил его производительность. Если значительное время тратится на копирование данных, я бы рассмотрел возможность использования других методов.
Конечно, еще одним соображением должно быть «собираемся ли мы когда-нибудь использовать две отдельные машины [или две виртуальные машины в одной системе] для решения этой проблемы. В этом случае лучше выбрать сетевое решение, даже если оно не САМОЕ быстрое». , я запустил локальный стек TCP на своих машинах на работе для тестов и получил около 20-30 Гбит / с (2-3 ГБ / с) с устойчивым трафиком.Необработанный memcpy в том же процессе дает около 50-100 ГБит / с (5-10 ГБ/с) (если только размер блока ДЕЙСТВИТЕЛЬНО крошечный и не помещается в кеш L1). Я не измерял стандартный канал, но ожидаю, что это где-то примерно посередине этих двух чисел. [Это цифры которые подходят для ряда различных довольно современных ПК среднего размера - очевидно, на ARM, MIPS или другом встроенном контроллере ожидайте меньшего числа для всех этих методов]
person
Mats Petersson
schedule
08.01.2013