节能旋转环

时间:2014-01-16 15:37:04

标签: c++ c assembly x86 x86-64

我正在编写一个监视全局变量变化的自旋循环。这有占据整个CPU核心的副作用,这很好,因为我使用的是多核机器。

我的问题是:它可以节能吗?我正在使用C ++,如果需要,可以访问x64程序集。

这是我的代码:

void monitor_changes(int*variable_to_monitor){
    int last_value=*variable_to_monitor;
    while(1){ //this is the spin loop - don't want the os to interrupt it, but can it be energy efficient?
        int cur_value=*variable_to_monitor;
        if (*variable_to_monitor!=last_value){
            printf("value has changed!");
            last_value=cur_value;
        }
    }
}

编辑:我不想使用OS服务,因为监控需要尽快做出反应。使用OS服务会引入延迟。

3 个答案:

答案 0 :(得分:3)

除非您有一个非常不寻常的用例,否则您的方法是错误的。您不应该使用自旋循环来监视全局变量的更改。相反,你应该向观察者发出全球变化的信号。如果使用pthread,请查看pthread_cond_signalpthread_cond_wait。各种C ++库也有这些,例如Boost有互斥和条件变量。一种老式的方法是使用管道,在显示器的管道上选择,并在更改全局时编写一个字符。

如果你确实需要监控全局,你可以考虑在检查之间休息(你需要多久知道),考虑你的操作系统是否有导致计划发生的事情,或者考虑pause说明 - 见:  http://x86.renejeschke.de/html/file_module_x86_id_232.html

答案 1 :(得分:2)

如果快速响应时间很重要,请仔细查看给定操作系统和服务的可能性。在尽力而为的计算机中(与实时相比)无论哪个字段指示,分辨率通常约为10毫秒。此外,OS服务需要时间来设置代码反应速度的下限。

除非你为专业设备编写了自己的低级驱动程序,否则我怀疑你的分辨率要好于10毫秒。

旋转环永远不会有利于提高能效。在现代处理器中,存在空闲/睡眠状态(C0,C1等),使得处理器在不使用时进入休眠状态。从这些空闲状态唤醒的延迟大约是usec。这比传统编译器生成的OS驱动程序,库和代码引入的延迟要少几个数量级。请注意,此处的重要字词是"未使用"。这些睡眠状态不会以任何有意义的方式影响性能,因为处理器无论如何都没有做任何事情。

我已经就这个问题做了一些写作。看看List of Useful Power and Power Management Articles, Blogs and References中的参考文献。 (令人尴尬地偏向我的材料。随着时间的推移,这将改变。)

以下是我更具体的建议:

(1)确定您需要的实际响应时间。     (a)如果要回应人的输入,你就不能在不到四分之一秒的时间内获得有意义的响应时间。     (b)如果要响应机器生成的事件,您不仅需要分析事件之间的最小增量,还需要分析通信机制引入的统计方差,例如:网络协议。

(2)确定您的系统能够做什么。除非你有专门的实时设备,例如,这很难得到。 RTOS,专业库和驱动程序。您可能需要进行一些实验和数据收集。

(3)找出你真正想要达到所需响应时间的设备。

现在让我们来看看现实。既然你问了这个问题,我猜你没有使用需要专业和昂贵的操作系统,库等的实时设备。我怀疑你使用的是使用标准操作系统的传统多核计算机(Linux,Windows, OSX,Android等),标准库和通用编译器(例如gcc)。我怀疑你能得到10毫秒以上的分辨率,我怀疑你需要的响应时间最多只能在100毫秒左右,如果你依赖人类输入则需要更高的响应时间。

不要使用旋转循环。从能效角度来看,这是最糟糕的事情,因为它可以防止处理器进入空闲状态。非空闲处理器功率可以> 30瓦。空闲功率可以<5W,延迟<100usec。如果使用旋转环,则功耗将> 30瓦。如果允许使用空闲状态,则总功耗可能<10瓦,而且不会对性能产生重大影响。

每隔50毫秒唤醒100毫秒以检查变量的变化,然后再回到睡眠状态。

此致

泰勒

你提出了一个很好的问题。关于该领域的问题存在很多误解。我不能提到造成同样错误的众所周知的应用程序。

答案 2 :(得分:1)

暂停指令之外的另一个选项是MONITOR / MWAIT。对于您正在寻找的内容,可能会有太高的延迟,但无论如何都要读取它:

http://semipublic.comp-arch.net/wiki/Monitor-Mwait

http://software.intel.com/en-us/articles/how-to-use-the-monitor-and-mwait-streaming-simd-extensions-3-instructions

https://blogs.oracle.com/dave/resource/mwait-blog-final.txt