(Начало - здесь)
API ZeroMQ позволяет отправлять и принимать сообщения напрямую, используя буфера данных приложения, без копирования данных. Эта технология называется нуль - копия, её применение позволяет увеличить производительность в некоторых приложениях.
О нуль-копии следует вспоминать в случае, когда вы отправляете большие блоки памяти (тысячи байт) с высокой частотой.
Делаем нуль-копию. С помощью zmq_msg_init_data() создается сообщение, которое ссылается на уже существующий блок данных вашего приложения, которое затем передается в zmq_msg_send():
Тип p_zmq_free_fn - указатель на функцию типа zmq_free_fn:
Когда создается сообщение, вы также передаете параметр - функцию, чтобы ZeroMQ смогла вызвать её для освобождения блока данных после завершения передачи сообщения.
Пример такой функции, предполагающий, что буфер представляет собой блок (длиной, скажем, в 1000 байт), выделенный в куче:
Пример:
Насчет параметра hint:
Библиотека ZeroMQ его просто копирует его значение из параметра hint функции
Судя по всему, он введен для особых случаев - например, когда требуется передать блок дополнительных данных в процедуру ffn: free_fn.
Еще раз отмечу, что вызывать zmq_msg_close() после отправки сообщения не нужно - libzmq выполнит вызов автоматически, когда сообщение будет отправлено.
Способа сделать нуль-копию на приеме - нет.
ZeroMQ предоставит вам буфер, который вы можете использовать сколько угодно, но не записывает данные напрямую в буферы вашего приложения.
При записи составных сообщений ZeroMQ отлично работает с нуль-копией. Для обычных сообщений вам понадобилось бы слить несколько сообщений в один буфер, а только потом отправлять. То есть, понадобилось бы выполнить копирование данных. А с ZMQ можно отправить несколько разных буферов, пришедших от разных источников, как отдельные кадры сообщения. Каждое поле отправляется как кадр, отделенный значением длины (префиксом). В приложении это выглядит как последовательность вызовов отправлений или приема. Однако, внутри ядра ZMQ, составное сообщение отправляется и принимается одним системным вызовом, что очень эффективно.
Дальше я расскажу о еще одном способе фильтрации входящих сообщений для схемы "Издатель - Подписчик". (Продолжение)
Нуль - копия (Zero-Copy).
API ZeroMQ позволяет отправлять и принимать сообщения напрямую, используя буфера данных приложения, без копирования данных. Эта технология называется нуль - копия, её применение позволяет увеличить производительность в некоторых приложениях.
О нуль-копии следует вспоминать в случае, когда вы отправляете большие блоки памяти (тысячи байт) с высокой частотой.
Делаем нуль-копию. С помощью zmq_msg_init_data() создается сообщение, которое ссылается на уже существующий блок данных вашего приложения, которое затем передается в zmq_msg_send():
function zmq_msg_init_data(msg: p_zmq_msg_t; data: Pointer; size: size_t; ffn: p_zmq_free_fn; hint: Pointer): Integer; cdecl; external libzmq;
Тип p_zmq_free_fn - указатель на функцию типа zmq_free_fn:
type p_zmq_free_fn = ^zmq_free_fn; zmq_free_fn = procedure(data: Pointer; hint: Pointer); cdecl;
Когда создается сообщение, вы также передаете параметр - функцию, чтобы ZeroMQ смогла вызвать её для освобождения блока данных после завершения передачи сообщения.
Пример такой функции, предполагающий, что буфер представляет собой блок (длиной, скажем, в 1000 байт), выделенный в куче:
procedure my_free (aData : Pointer; aHint : Pointer); cdecl; begin Freemem(aData); end;
Пример:
procedure my_free(aBuf, aHint : Pointer); cdecl; begin FreeMem(aBuf); end; var fMsg : zmq_msg_t; fData : Pointer; ... begin ... GetMem(fData, 1000); FillChar(fData^, 1000, 'z'); zmq_msg_init_data(@fMsg, fData, 1000, @my_free, nil); zmq_msg_send(@fMsg,fSocketSyncService, 0);
Насчет параметра hint:
free_fn = procedure(data, hint: Pointer); cdecl;
Библиотека ZeroMQ его просто копирует его значение из параметра hint функции
function zmq_msg_init_data( var msg: zmq_msg_t; data: Pointer; size: size_t; ffn: free_fn; hint: Pointer ): Integer; cdecl; external libzmq;
Судя по всему, он введен для особых случаев - например, когда требуется передать блок дополнительных данных в процедуру ffn: free_fn.
Еще раз отмечу, что вызывать zmq_msg_close() после отправки сообщения не нужно - libzmq выполнит вызов автоматически, когда сообщение будет отправлено.
Способа сделать нуль-копию на приеме - нет.
ZeroMQ предоставит вам буфер, который вы можете использовать сколько угодно, но не записывает данные напрямую в буферы вашего приложения.
При записи составных сообщений ZeroMQ отлично работает с нуль-копией. Для обычных сообщений вам понадобилось бы слить несколько сообщений в один буфер, а только потом отправлять. То есть, понадобилось бы выполнить копирование данных. А с ZMQ можно отправить несколько разных буферов, пришедших от разных источников, как отдельные кадры сообщения. Каждое поле отправляется как кадр, отделенный значением длины (префиксом). В приложении это выглядит как последовательность вызовов отправлений или приема. Однако, внутри ядра ZMQ, составное сообщение отправляется и принимается одним системным вызовом, что очень эффективно.
Дальше я расскажу о еще одном способе фильтрации входящих сообщений для схемы "Издатель - Подписчик". (Продолжение)
Комментариев нет :
Отправить комментарий