我想以高分辨率(以 us/ns 为单位)测量两个 python 进程之间的 Zeromq 延迟(Windows 10)。
这是我的代码。
子.py
import sys
import zmq
import time
port = "5556"
if len(sys.argv) > 1:
port = sys.argv[1]
int(port)
if len(sys.argv) > 2:
port1 = sys.argv[2]
int(port1)
# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
print('connecting to publisher')
socket.connect ("tcp://localhost:%s" % port)
if len(sys.argv) > 2:
socket.connect ("tcp://localhost:%s" % port1)
topicfilter = "10001"
socket.setsockopt_string(zmq.SUBSCRIBE, topicfilter)
total_value = 0
while True:
string = socket.recv()
got_time = time.time() # resolution in windows 10: 15.6ms
topic, msgdata = string.split()
dur = got_time - float(msgdata)
print('it took %.5fms from pub' % (dur*1000))
pub.py
import zmq
import random
import sys
import time
port = "5556"
if len(sys.argv) > 1:
port = sys.argv[1]
int(port)
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)
topic = 10001
while True:
msgdata = time.time() # resolution in windows 10: 15.6ms
socket.send_string("%d %.5f" % (topic, msgdata))
print("topic:%d, msg:%.5f" % (topic, msgdata))
time.sleep(1)
但是,由于
time.time()
函数在Windows 10中的分辨率仅为15.6ms(Windows默认计时器周期),因此我无法用代码测量低于15.6ms的延迟。
所以我考虑使用
time.perf_counter()
函数,它具有微秒分辨率,但它在测量两个过程的时间差方面也没有用,因为根据doc,
time.perf_counter()
函数的参考点未定义。
有没有其他方法可以高分辨率(微秒或纳秒单位)测量两个Python进程之间的时间差?
是的,有:ZeroMQ 有一个内置工具可以执行此操作,该工具独立于平台并且确实非常好用。
aClk = zmq.Stopwatch() // creates a Stopwatch instance
...
..
.
aClk.start();_=aProcessUnderTEST();aClk.stop() // measure an embedded latency
2169L // <-------------------latency[us]
.stop()
方法返回一个长数字 ( 1234L
),表示持续时间 ,分辨率为 [us]。
提示:在深入测试性能细节时避免任何打印和内存分配操作(总是预分配,总是分配函数的返回值,而不是将解释器的结果值repr/打印开销包含在测量嵌入代码段 == 通过分配给
repr()
(特殊符号(变量),没有任何分配开销))来避免
_
开销。
仍然有一些问题需要解决(或需要注意):
-在分布式主机上,(非本地进程开始/结束)您需要找到并同步一个公共参考时钟来计算有意义的差异,或者必须重新安排测试以在消息/中形成循环信号传输来回测量同一 refClk 端。对于高分辨率时钟的其他方面(具有亚
1E-6
分辨率)、单调性(不受 NTP 调整影响),请检查 time.process_time()
、time.perf_counters()
,并且可以使用更复杂的场景来进行差异测量,因为一个消息触发测试测量的开始,第二个到达触发测试测量的结束,携带发起方侧消息间持续时间(处理、预期延迟等)开销(在 [us]
中)作为有效负载(从接收方的结果替换)。无论如何,在处理次[us]
事件时要小心下面提到的系统性不确定性。
- 期望操作系统对各种 ZeroMQ 传输类进行干预。例如,
tcp://
传输类是 Windows 缓冲的一个主题,并且已经在 Windows TCP/IP 堆栈上发布了严重不可预测的延迟有线传输(谷歌它们,存在对策,也谷歌它们)。
- 预计 O/S 调度程序 会影响
aProcessUnderTEST
在所有其他系统+用户处理和优先资源处理中的执行方式。