1

我正在使用 Win32 多媒体计时器在发送大量 UDP 数据包之间设置延迟,但我发现由此产生的延迟比它应该的要长得多。大约 40 毫秒的延迟有时接近 1000 毫秒,即使在使用 Windows Miltimedia 计时器并提高计时器分辨率时也是如此。下面是我使用的代码的简化版本:

if( timeGetDevCaps(&tc,sizeof(TIMECAPS)) == TIMERR_NOERROR) 
    {
    timeRes = min( max(tc.wPeriodMin,1), tc.wPeriodMax);
    timeBeginPeriod(timeRes);
    printf("Timer Res: %u\n", timeRes);
    }
/* ... */
while( ptrHead )
    {
    NALU_t *ptrLink = ptrHead;
    unsigned long tsNALU = ptrLink->timestamp - tsFirst;
    printf("Timestamp: %umsec\n", ptrLink->timestamp / 90 );
    int idxPort;
    for(idxPort=0;idxPort<12;idxPort++)
        {
        ip4Addr.sin_port = htons( 60000 + idxPort );
        struct sockaddr *saAddr = (struct sockaddr*)&ip4Addr;
        sendto(fdSocket,(char*)ptrLink->ptrData,ptrLink->lenData,
           0,saAddr,lenAddr);
        }
    if( 1 )
        {
        unsigned long millis = (tsNALU - tsPrev) / 90;
        valTime.QuadPart  = 10000;
        valTime.QuadPart *= millis;
        valTime.QuadPart *= -1;
        if(SetWaitableTimer(hdlTimer,&valTime,0,NULL,NULL,TIME_ONESHOT))
            WaitForSingleObject(hdlTimer,INFINITE);
        }
    tsPrev = tsNALU;
    ptrHead = ptrLink->next;
    free( ptrLink );
    }

怀疑问题是 Windows7 不再保证在由事件而不是回调发出信号时解决计时器,但我不愿意使用后者。任何人都知道为什么即使是单线程测试用例中所谓的高分辨率计时器也如此不准确?

4

2 回答 2

1

从随后的实验来看,我最好的猜测是 Windows 在 CPU 内核之间移动线程(可能是出于负载平衡的原因——这是在四核 i7 上)会破坏计时功能。我曾经SetThreadAffinityMask()将我的计时关键线程锁定到一个 CPU(以及我的非计时线程锁定到所有其他内核),这已经解决了问题。

于 2012-08-31T16:45:09.173 回答
1

如果时间很关键,最好在繁忙的循环中运行(如果需要,您可以使用 Sleep(0) 放弃每次迭代的时间片),使用 QueryPerformanceCounter() API 来测量经过的时间。

于 2012-08-31T05:49:29.180 回答