【问题标题】:Best Practice for Stopwatch in multi processors machine?多处理器机器中秒表的最佳实践?
【发布时间】:2010-11-12 01:53:01
【问题描述】:

我找到了一个很好的question 用于测量功能性能,答案建议使用秒表如下

Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed

但是,如果您在多处理器机器下运行,这是否有效?线程可以切换到另一个处理器,可以吗? 同样的事情也应该在 Enviroment.TickCount 中。 如果答案是肯定的,我应该将我的代码包装在 BeginThreadAffinity 中,如下所示

Thread.BeginThreadAffinity();
Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed
Thread.EndThreadAffinity();

附言

切换可以发生在线程级别,而不仅仅是处理器级别,例如,如果函数在另一个线程中运行,那么系统可以将其切换到另一个处理器,如果发生这种情况,在切换后秒表是否有效?

我不仅使用 Stopwatch 进行性能测量,还使用 ​​Thread.Sleep 模拟计时器功能(以防止调用重叠)

【问题讨论】:

    标签: c# multiprocessor performance


    【解决方案1】:

    如果函数本身不是多线程的(例如,它不会产生其他线程/进程并等待它们完成),那么唯一的问题就是您的机器。

    如果您的机器忙于做其他事情,它可能会使您的测试无效(例如,在进行 CPU 密集型测试时编码 H.264 视频)。同样,如果您使用所有物理内存来测试受内存限制的东西,那么它可能会使您的结果无效。

    因此,一般原则是在进行此类测试时,机器应处于最小至正常负载下。除此之外没有多处理问题。是的,程序可以在运行时交换内核,但这样做的开销要么是你测量时间的一小部分,要么是测量时间太小,以至于系统时间测量的粒度是一个问题。

    【讨论】:

    • 如果函数在后台线程中运行,这意味着函数线程可以切换到另一个处理器,从而导致测量错误
    • 根据 MSDN:“后台线程与前台线程相同,只是后台线程不会阻止进程终止。”参考:msdn.microsoft.com/en-us/library/…
    • @Tormod Fjeldskår,前台/后台线程可以切换到其他处理器,所以我不关心它的类型,但我在评论中提到了它,例如没有更多
    【解决方案2】:

    我认为您是在询问 Stopwatch 的低级实现以及在执行过程中切换处理器是否会使行为无效。该实现确实在内部使用了 QueryPerformanceCounter(请参阅 MS BCL 参考源;我至少在 .NET 4.0 中确认了它。)

    此 API 的 MS documentation 声明:

    在多处理器计算机上,哪个处理器无关紧要 叫。但是,您可以在不同的处理器上获得不同的结果 由于基本输入/输出系统 (BIOS) 或硬件中的错误 抽象层 (HAL)。

    所以,你是对的;原则上,这无关紧要,但该评论表明已经观察到实现与预期接口不符的实例。如果您想保证测量的正确性,您可以使用线程亲和性,如您所述。也就是说,我猜观察到的任何错误都非常小,因为差异很大将是一个非常严重的 BIOS 或 HAL 错误。

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多