多处理器机器中秒表的最佳实践?
我发现了一个很好的问题测量函数性能,答案建议使用秒表,如下所示
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();
P.S
切换不仅可以在处理器级别上进行,还可以在线程级别上进行,例如,如果该函数正在另一个线程中运行,则系统可以将其切换到另一个处理器,如果出现这种情况,切换后秒表还有效吗?
我不仅使用秒表进行性能测量,还使用 Thread.Sleep 模拟计时器功能(以防止调用重叠)
I found a good question for measuring function performance, and the answers recommend to use Stopwatch as follows
Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed
But is this valid if you are running under multi processors machine? the thread can be switched to another processor, can it?
Also the same thing should be in Enviroment.TickCount.
If the answer is yes should I wrap my code inside BeginThreadAffinity as follows
Thread.BeginThreadAffinity();
Stopwatch sw = new Stopwatch();
sw.Start();
//DoWork
sw.Stop();
//take sw.Elapsed
Thread.EndThreadAffinity();
P.S
The switching can occur over the thread level not only the processor level, for example if the function is running in another thread so the system can switch it to another processor, if that happens, will the Stopwatch be valid after this switching?
I am not using Stopwatch for perfromance measurement only but also to simulate timer function using Thread.Sleep (to prevent call overlapping)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果函数本身不是多线程的(例如,它不会生成其他线程/进程并等待它们完成),那么唯一的问题是您的机器。
如果您的机器正忙于做其他事情,则可能会使您的测试无效(例如,在进行 CPU 密集型测试时编码 H.264 视频)。 同样,如果您使用所有物理内存来测试受内存限制的内容,那么它可能会使您的结果无效。
所以总的原则是,进行此类测试时,机器应处于最小到正常的负载下。 除此之外,不存在多处理问题。 是的,程序可以在运行时交换核心,但这样做的开销要么只占测量时间的一小部分,要么测量的时间太小以至于系统时间测量的粒度成为问题。
If the function itself isn't multithreaded (eg it doesn't spawn other threads/processes and wait for them to complete) then the only issue is your machine.
If your machine is busy doing other things it could invalidate your test (eg encoding a H.264 video while doing a CPU-bound test). Likewise if you use all the physical memory on testing something that is memory-bound then it could invalidate your results.
So the general principle is that the machine should be under a minimal-to-normal load when conducting such tests. Other than that there isn't a multiprocessing issue. Yes, the program could swap cores while running but the overhead of doing that is either a tiny percentage of your measured time or the measured time is so small that the granularity of the system's time measurement is an issue.
我认为您是在询问秒表的低级实现以及在执行过程中切换处理器是否会使行为无效。 该实现确实在内部使用了 QueryPerformanceCounter(请参阅 MS BCL 参考源;我至少在 .NET 4.0 中确认了它。
)此 API 的 /desktop/ms644904%28v=vs.85%29.aspx" rel="nofollow">MS 文档指出:
所以,你是对的; 原则上,这应该不重要,但是这个评论表明已经观察到实现不符合预期接口的情况。 如果您想保证测量的正确性,您可以使用线程亲和力,如您所述。 也就是说,我猜观察到的任何错误都很小,因为较大的差异将是相当严重的 BIOS 或 HAL 错误。
I think you're asking about the low-level implementation of Stopwatch and whether switching processors in the middle of execution could invalidate the behavior. The implementation does use QueryPerformanceCounter internally (see the MS BCL Reference Sources; I've confirmed it in .NET 4.0 at least.)
The MS documentation for this API states:
So, you are correct; in principle, it shouldn't matter, but this comment suggests there have been observed instances where the implementation does not accord with the intended interface. If you want to guarantee the correctness of the measurement, you can use thread affinity, as you stated. That said, I'm guessing any errors observed are quite small, as a large difference would be a pretty serious BIOS or HAL bug.