在 Windows 10 中以高分辨率测量两个 python 进程之间的 zmq 延迟

问题描述 投票:0回答:1

我想以高分辨率(以 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进程之间的时间差?

python python-3.x time zeromq
1个回答
1
投票

是的,有: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
在所有其他系统+用户处理和优先资源处理中的执行方式。

© www.soinside.com 2019 - 2024. All rights reserved.