我在C#中有一个轮询循环,它需要在平均< EDIT>上每100微秒轮询一次(当然,由于内核短缺,没有过多的抢占线程上下文切换)< /EDIT>。
由于没有时间重新安排时间,睡眠(1)将不起作用。
因此,我决定指定一个线程(在实践中,在设置亲和力时使用一个核心),并为每次迭代使用一组循环的Thread.SpinWait。虽然这很好,但它消耗了不必要的能量。100微秒足以让CPU暂停(而不足以将线程临时从调度程序中删除,因为Windows时间片将是长时间的方法)。
相反,我想使用Intel暂停指令,但我不确定它是否会触发Intel CPU来挂起硬件线程。英特尔声称它保留了电源,应该在旋转循环中使用,但由于暂停时间长达100微秒,我真的希望核心进入C1模式睡眠。
有什么想法吗?
编辑:我正在轮询第三方API,所以没有需要阻止的同步事件。
发布于 2012-08-07 13:25:38
当然,使用同步原语和计时器是避免CPU/耗电繁忙等待的首选方法。然而,如果你需要如此频繁的投票-没有办法通过传统的手段,至少在用户模式下实现这一点。
您可以做的一件简单的事情是在循环中包含一个pause CPU指令。在MSVC中,它是通过一个内在的YieldProcessor()方法实现的。
除此之外,可能只在内核模式编程中。在那里你可以使用高精度的多媒体计时器.
编辑:
关于SetWaitableTimer。这可能是一种选择。与“传统”Win32等待函数不同(如Sleep、WaitForSingleObject等)它使用高精度的超时作为参数。
然而,用户模式定时器本质上是异步。让我们假设定时器以高精度激活(这并不明显,“传统的”Win32等待函数的精度可达数十毫秒的数量级)。定时器激活后,它释放适当的等待线程。但是线程调度器不需要立即将这个线程附加到执行中--它可能会等待下一个时间片。如果存在并发线程,甚至更多地延迟线程的执行。
最后,这个想法似乎值得一试。但是,如果这或多或少等同于使用Sleep,我也不会感到惊讶。
发布于 2012-08-07 14:14:55
考虑到您的等待时间很长,您可能会发现SSE3内存区域监视器在省电方面效率要高得多,然而,它并不是真正设计为阻塞旋转等待,而是作为一个可报警的等待,但可能仍然是一个可行的替代方案。
但是,在C#中实现这一点需要一个外部DLL,它提供了C++本质(_mm_mwait和_mm_monitor)的接口。
https://stackoverflow.com/questions/11837830
复制相似问题