在多个处理器上安全的Stopwatch.GetTimestamp()替代方案

时间:2014-06-04 09:39:36

标签: .net multiprocessing clock multicore

我需要像Stopwatch.GetTimestamp()这样的时钟

  1. 获取值
  2. 时的开销很小
  3. 精确到至少1毫秒(不减小os宽定时器间隔)
  4. 不必与实际时间挂钩(例如DateTime.Now
  5. 单调增加,但不一定严格(在相同的毫秒内多次调用它,精度为1ms会产生相同的值)
  6. 在多个核心和处理器上同时维护以上所有内容
  7. Stopwatch似乎fail to provide the last of these properties

      

    在多处理器计算机上,哪个处理器无关紧要   线程运行。但是,由于BIOS或硬件中的错误   抽象层(HAL),您可以获得不同的计时结果   不同处理器。要指定线程的处理器关联,请使用   ProcessThread.ProcessorAffinity方法。

    为了实现真正的并发性,出于显而易见的原因,我无法将所有线程都固定到单个处理器上。

    我可以在.net中使用的任何替代方案吗?或者上述警告是否过时/仅限于某些罕见的模型(我的生产环境不太可能存在)?

    修改

    这是我的主要关注点:我不介意在不同的处理器上关闭一个(例如毫秒)左右的值,但无论从哪个处理器中检索它们,它们都必须总是或多或少相同。 / p>

3 个答案:

答案 0 :(得分:2)

MS实际上有关于Stopwatch底层的计数器的深入文章。 Acquiring high-resolution time stamps

相关摘录:


通常,性能计数器结果在多核和多处理器系统中的所有处理器上都是一致的,即使在不同的线程或进程上进行测量也是如此。以下是此规则的一些例外情况:

  • 在某些处理器上运行的Windows Vista之前的操作系统可能会违反此一致性,原因如下:
    • 硬件处理器具有非不变的TSC,并且BIOS未正确指示此情况。
    • 使用的TSC同步算法不适合具有大量处理器的系统。
  • 当您比较从不同线程获取的性能计数器结果时,请考虑相差±1 tick的值,以使其具有不明确的排序。如果时间戳是从同一个线程中获取的,则该±1刻度不确定性不适用。在此上下文中,术语tick表示等于1÷的时间段(从QueryPerformanceFrequency获得的性能计数器的频率)。

答案 1 :(得分:1)

The way it is even on buggy systems实际上已经足够好(对我来说):

  • GetTimestamp() - stampTakenEarlierOnADifferentProcessor的结果可能会变为负数 - 某些应用程序存在问题,但不适用于我的用例
  • 我们正在谈论微秒 - 上衣
  • 不同的处理器不随时间漂移:好

答案 2 :(得分:-1)

由于你只需要间隔测量你的秒表,但你不能从不同的处理器上运行的不同线程访问同一个实例(如果我理解你的话,如果我错了,请告诉我),你可以创建一个每个线程的新实例:

ThreadLocal<Stopwatch> watch = new ThreadLocal<Stopwatch>(() => new Stopwatch());

每个实例应正确计算从开始时起的时间间隔。

作为替代方案,您可以获取DateTime.Now属性并根据需要发送文本。它与.GetTimeStamp()具有相同的语义(对我而言)。