我有两个用C编写的进程设置了[[PUSH/PULL
ZeroMQ套接字,而Python进程中的两个线程则镜像了PUSH/PULL
套接字。从C进程到Python进程每秒大约发送80-300个轻量级消息(<30字节),从Python进程到C进程大约发送10-30条类似消息。
我的ZeroMQ套接字设置在系统之间没有变化,我将LINGER
设置为0,我在0到100毫秒之间尝试了RCVTIMEO
,并且我尝试在0到50之间改变了BACKLOG
,但两种方式都没有区别。我尝试使用多个IO线程并设置套接字线程相似性,但也无济于事。对于PUSH
套接字,我将连接tcp://localhost:#####
上的套接字,并将PULL
套接字绑定到tcp://*:#####
。我还使用了ipc:///tmp/...
,正在发送和接收消息,但是延迟仍然存在于32位系统上。
我研究了接收消息之间的其他Python步骤,它们看起来最多不会花费超过一毫秒的时间。当我为socket.recv(0)
计时时,即使该插座的RCVTIMEO
设置为0,也高达0.02秒。
关于我为什么会在新的32位平台上而不在其他平台上看到此行为的任何建议?我可能在所有错误的地方都看过吗?
这里有一些代码可以帮助解释:
连接和_recv()
类方法大致如下:
def _connect(self):
self.context = zmq.Context(4)
self.sink = self.context.socket(zmq.PULL)
self.sink.setsockopt(zmq.LINGER, 0)
self.sink.setsockopt(zmq.RCVTIMEO, 100)
self.sink.setsockopt(zmq.BACKLOG, 0)
self.sink.bind("tcp://*:55755")
def _recv(self):
while True:
msg = None
try:
msg = self.sink.recv(0) # Use blocking or zmq.NOBLOCK, still appears to be slow
except zmq.Error
... meaningful exception handle here
# This last step, when timed usually takes less than a millisecond to process
if msg:
msg_dict = utils.bytestream_to_dict(msg) # unpacking step (negligible)
if msg_dict:
self.parser.parse(msg_dict) # parser is a dict of callbacks also negligible
在C程序方面
zmq_init (4); void *context = zmq_ctx_new (); /* Connect the Sender */ void *vent = zmq_socket (context, ZMQ_PUSH); int timeo = 0; int timeo_ret = zmq_setsockopt(vent, ZMQ_SNDTIMEO, &timeo, sizeof(timeo)); if (timeo_ret != 0) error("Failed to set ZMQ recv timeout because %s", zmq_strerror(errno)); int linger = 100; int linger_ret = zmq_setsockopt(vent, ZMQ_LINGER, &linger, sizeof(linger)); if (linger_ret != 0) error("Failed to set ZMQ linger because %s", zmq_strerror(errno)); if (zmq_connect (vent, vent_port) == 0) info("Successfully initialized ZeroMQ ventilator on %s", vent_port); else { error("Failed to initialize %s ZeroMQ ventilator with error %s", sink_port, zmq_strerror(errno)); ret = 1; } ... /* When a message needs to be sent it's instantly hitting this where msg is a char* */ ret = zmq_send(vent, msg, msg_len, ZMQ_NOBLOCK);
在目标32位系统上运行的docker上lstopo--v --no-io
Machine (P#0 local=1019216KB total=1019216KB HardwareName="Freescale i.MX6 Quad/DualLite (Device Tree)" HardwareRevision=0000 HardwareSerial=0000000000000000 Backend=Linux LinuxCgroup=/docker/d2b0a3b3a5eedb7e10fc89fdee6e8493716a359597ac61350801cc302d79b8c0 OSName=Linux OSRelease=3.10.54-dey+g441c8d4 OSVersion="#1 SMP PREEMPT RT Tue Jan 28 12:11:37 CST 2020" HostName=db1docker Architecture=armv7l hwlocVersion=1.11.12 ProcessName=lstopo) Package L#0 (P#0 CPUModel="ARMv7 Processor rev 10 (v7l)" CPUImplementer=0x41 CPUArchitecture=7 CPUVariant=0x2 CPUPart=0xc09 CPURevision=10) Core L#0 (P#0) PU L#0 (P#0) Core L#1 (P#1) PU L#1 (P#1) Core L#2 (P#2) PU L#2 (P#2) Core L#3 (P#3) PU L#3 (P#3) depth 0: 1 Machine (type #1) depth 1: 1 Package (type #3) depth 2: 4 Core (type #5) depth 3: 4 PU (type #6)
Q:每秒从C进程发送到Python进程的消息大约为80-300轻量(<30字节),从Python进程到C进程大约发送10-30个类似的消息。
a),有关从python向C发送任何消息的信息为零
b
)300 [Hz]
<30 B有效载荷,按照ZeroMQ能力而言是零]c
)python自从以来(几乎肯定会一直如此)在意义上是纯[SERIAL]
,无论有多少Thread
实例,因此任何执行都必须等到它获得了POSACK的GIL-lock所有权,阻止了任何其他工作,因此一步一步地恢复了纯[SERIAL]
的工作...但又付出了GIL-lock的额外费用已添加握手。鉴于所有进程都在相同的硬件平台上运行(请参见tcp://
[localhost
...
),所以没有理由产生多达(4 + 4)-IO线程(其中python报告一次只能读取一个线程和一个线程(slo-mo)而无法“利用”它们,因为上面只报告了4个CPU内核通过lstopo
摘录:Machine (995MB)
+Package L#0
Core L#0 +PU L#0 (P#0)
Core L#1 +PU L#1 (P#1)
Core L#2 +PU L#2 (P#2)
Core L#3 +PU L#3 (P#3)
e)ISO-OSI-L2 / L3参数可以调整,但是在所有较大的延迟源都被消除之后。
lstopo-no-graphics -.ascii
提供更好的视图
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Machine (31876MB) │
│ │
│ ┌────────────────────────────────────────────────────────────┐ ┌───────────────────────────┐ │
│ │ Package P#0 │ ├┤╶─┬─────┼┤╶───────┤ PCI 10ae:1F44 │ │
│ │ │ │ │ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │ │ ┌────────────┐ ┌───────┐ │ │
│ │ │ L3 (8192KB) │ │ │ │ │ renderD128 │ │ card0 │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │ │ └────────────┘ └───────┘ │ │
│ │ │ │ │ │ │
│ │ ┌──────────────────────────┐ ┌──────────────────────────┐ │ │ │ ┌────────────┐ │ │
│ │ │ L2 (2048KB) │ │ L2 (2048KB) │ │ │ │ │ controlD64 │ │ │
│ │ └──────────────────────────┘ └──────────────────────────┘ │ │ │ └────────────┘ │ │
│ │ │ │ └───────────────────────────┘ │
│ │ ┌──────────────────────────┐ ┌──────────────────────────┐ │ │ │
│ │ │ L1i (64KB) │ │ L1i (64KB) │ │ │ ┌───────────────┐ │
│ │ └──────────────────────────┘ └──────────────────────────┘ │ ├─────┼┤╶───────┤ PCI 10bc:8268 │ │
│ │ │ │ │ │ │
│ │ ┌────────────┐┌────────────┐ ┌────────────┐┌────────────┐ │ │ │ ┌────────┐ │ │
│ │ │ L1d (16KB) ││ L1d (16KB) │ │ L1d (16KB) ││ L1d (16KB) │ │ │ │ │ enp2s0 │ │ │
│ │ └────────────┘└────────────┘ └────────────┘└────────────┘ │ │ │ └────────┘ │ │
│ │ │ │ └───────────────┘ │
│ │ ┌────────────┐┌────────────┐ ┌────────────┐┌────────────┐ │ │ │
│ │ │ Core P#0 ││ Core P#1 │ │ Core P#2 ││ Core P#3 │ │ │ ┌──────────────────┐ │
│ │ │ ││ │ │ ││ │ │ ├─────┤ PCI 1002:4790 │ │
│ │ │ ┌────────┐ ││ ┌────────┐ │ │ ┌────────┐ ││ ┌────────┐ │ │ │ │ │ │
│ │ │ │ PU P#0 │ ││ │ PU P#1 │ │ │ │ PU P#2 │ ││ │ PU P#3 │ │ │ │ │ ┌─────┐ ┌─────┐ │ │
│ │ │ └────────┘ ││ └────────┘ │ │ └────────┘ ││ └────────┘ │ │ │ │ │ sr0 │ │ sda │ │ │
│ │ └────────────┘└────────────┘ └────────────┘└────────────┘ │ │ │ └─────┘ └─────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │ └──────────────────┘ │
│ │ │
│ │ ┌───────────────┐ │
│ └─────┤ PCI 1002:479c │ │
│ └───────────────┘ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘