首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么一个条件变量要修复我们的功耗?

为什么一个条件变量要修复我们的功耗?
EN

Stack Overflow用户
提问于 2015-03-27 20:58:26
回答 2查看 1.1K关注 0票数 13

我们在mac上做音频播放器项目,注意到耗电量太高了(大约是google的7倍)。

我使用了xcode的能源分析工具,其中一个问题是我们有太多的cpu唤醒开销。

根据xcode:

每次CPU从空闲状态中醒来时,都会产生相应的能量损失。如果唤醒率很高,并且每个唤醒的CPU利用率都很低,那么您应该考虑批处理工作。

我们把问题缩小到了一个睡眠功能电话。

在我们的代码中,音频解码器是一个产生音频数据并将它们插入到消费者--音频播放器中的生产者。我们的音频播放器基于OpenAL,它为音频数据提供了一个缓冲区。

因为音频播放器可能比生产者慢,所以在向音频播放器提供新的音频数据之前,我们总是检查缓冲区的可用性。如果没有可用的缓冲区,我们需要休息一段时间,然后再试一次。所以代码看起来是:

代码语言:javascript
复制
void playAudioBuffer(Data *data)
{
    while(no buffer is available)
    {
         usleep()
    }
    process data.
}

知道我们的睡眠是个问题,我们做的第一件事就是简单地删除usleep()。(因为OpenAL似乎不提供回调或任何其他方式,所以轮询似乎是唯一的选择。)这样做后,我们成功地将耗电量减少了一半。

然后,昨天,我们试着

代码语言:javascript
复制
for(int i =0; i<attempts; ++i)
{
    std::unique_lock<std::mutex> lk(m);
    cv.wait_for(lk, 3, []{
                            available = checkBufferAvailable(); 
                            return available;
                         })

    if (available)
    {
         process buf;
    }
 }

这是我们偶然尝试的一个实验。从逻辑上讲,这对我们来说没有意义,因为它执行同样的等待。而且条件变量的使用是不正确的,因为变量"available“仅由一个线程访问。但是它实际上降低了我们90%的能耗,线程的cpu使用率下降了很多。现在我们比铬更好。但是,与下面的代码不同,条件变量是如何实现的呢?为什么它能省下我们的能量?

代码语言:javascript
复制
mutex lock;
while(condition is false)
{
    mutex unlock;
    usleep();
    mutex lock;
}
...
mutex unlock
...

(我们使用mac的活动监视器(能源数量)和cpu使用情况分析工具来测量能耗。)

EN

回答 2

Stack Overflow用户

发布于 2015-04-16 14:40:56

我可能错了,但据我所知,当您使用条件变量实现等待缓冲区数据收入时。它所做的主要工作是将呈现此条件变量的线程置于休眠状态,直到与其关联的信号唤醒该线程。这就是为什么更少的唤醒开销和更有效地使用资源的原因。

下面是在Linux中使用线程的链接,我在其中读到了这些链接:

  • POSIX线程第1部分
  • POSIX线程第2部分
  • POSIX线程第3部分

也许这会给你一些理解为什么和如何发生。

再说一遍,我不完全确定我是否完全正确,但在我看来,这似乎是一个正确的方向。

对不起我的纯正英语。

票数 1
EN

Stack Overflow用户

发布于 2015-04-16 14:55:23

如果您希望在Mac或iOS上尽可能降低能耗,那么至少可以使用dispatch_semaphore_t来准确地等待缓冲区已满,或者将一些块传递给缓冲区填充代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29310100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档