我正在将延迟测量构建到我正在构建的通信中间件中。我的工作方式是我定期从我的发布应用程序发送探测消息。订阅应用程序接收此探测,缓存它,并在他们选择的时候发回回信号,注意msg保持“保持”的时间。订阅应用程序接收这些回声并计算延迟为(now() - time_sent - time_on_hold)/ 2.
这种方法有效,但是当“保持时间”大于0时,数字差异很大(3x)。即如果我立即回复msg,我的开发环境会大约50us,如果我等待,则发送msg返回时间跳到150us(虽然我在任何时候都会打折)。我使用QueryPerfomanceCounter进行所有测量。
这一切都在一个Windows 7框中。我在这里缺少什么?
TIA。
答案 0 :(得分:0)
好的,我已经编辑了我的答案以反映你的答案:抱歉延迟,但我没有注意到你通过创建答案详细阐述了这个问题。
从功能上看,你似乎没有做错任何事。
我认为,当您在localhost条件之外分发应用程序时,额外的100us(如果它确实大致不变)与运行网络的平均延迟相比将变得微不足道。
为了回答您的问题,我认为服务器端存在需要调查的线程/中断调度问题,因为您似乎没有在客户端上执行任何未考虑的事情。
尝试以下测试方案:
有希望的是,两个客户都会在大致相同的时间发回他们的探测答案,并且在睡眠/等待之后(执行暴露问题的动作)。目标是尝试让其中一个客户响应“唤醒”发布者,以查看下一个客户端的答案是否会立即得到处理。
如果其中一个返回的探测器不显示异常(很可能是第二个响应),则可能指向发布者线程从睡眠周期唤醒的事实(在recv 1st responce上)并立即可以处理第二个回复。
同样,如果事实证明100us延迟大致不变,则它将是1ms的±10%,这是适用于真实世界网络条件的时间范围。
答案 1 :(得分:0)
更多信息。我使用以下方法来衡量时间:
static long long timeFreq;
static struct Init
{
Init()
{
QueryPerformanceFrequency((LARGE_INTEGER*) &timeFreq);
}
} init;
long long OS::now()
{
long long result;
QueryPerformanceCounter((LARGE_INTEGER*)&result);
return result;
}
double OS::secondsDiff(long long ts1, long long ts2)
{
return (double) (ts1-ts2)/timeFreq;
}
在发布方面,我做了类似的事情:
Probe p;
p.sentTimeStamp = OS::now();
send(p);
Response r = recv();
latency=OS::secondsDiff(OS::now()- r.sentTimeStamp) - r.secondsOnHoldOnReceiver;
在接收方:
Probe p = recv();
long long received = OS::now();
sleep();
Response r;
r.sentTimeStamp = p.timeStamp;
r.secondOnHoldOnReceiver = OS::secondsDiff(OS::now(), received);
send(r);