【问题标题】:Why does this C++ program not use 100% CPU but only 10%为什么这个 C++ 程序不使用 100% CPU 而只使用 10%
【发布时间】:2013-02-12 18:20:11
【问题描述】:

这个程序没有使用所有的 cpu 电源。 我期待它接管 CPU 并尽可能快地运行代码,但它只使用 10 max

#include <iostream>

using namespace std;

int main(void) {
    unsigned long long x = 600851475143;
    unsigned long long i = x-1;

    while(i <= x) {
            cout << "\r";
            cout << i;

            if((x % i) == 0) {
                    cout << "\n\n";
                    cout << i;

                    break;
            }

            i--;
    }

    system("pause");
}

最多只能达到 10%

【问题讨论】:

  • 因为它只会最大化其中一个核心。
  • 由于你的程序简单,只需要10%的CPU就可以运行...
  • 因为你的couts.
  • 也许如果您的程序计算 1 到 100,000,000,000,000 之间的每个素数。把一些 BigInts 扔进去找乐子。
  • 让程序使用所有内核是一个根本性的难题。它被称为多线程(或并行编程,或多处理等)。有关于它的书。简短的版本是你需要将工作分成几块,创建线程,并给每个线程分配一份工作。

标签: c++ performance cpu


【解决方案1】:

速度可能受限于输出设备的速度。如果将输出通过管道传输到磁盘上的文件,它将受到磁盘速度的限制。如果您只是写入控制台,它将受到控制台速度的限制。无论哪种方式,CPU 都不会成为限制。

编辑:由于有些人显然不太了解代码,也许最好简化一下。让我们通过省略if 语句来简化循环,只留下:

unsigned long long x = 600851475143;
unsigned long long i = x-1;

while(i <= x) {
        cout << "\r";
        cout << i;
        i--;
}

所以,它的作用是从 600851475143 开始,倒数到 0,然后在 i 环绕到 std::numeric_limits&lt;unsigned long long&gt;::max() 时停止(通常为 264-1)。

现在,如果我们重新添加 if 语句,我们几乎可以忽略它所控制的 body,但我们确实会在每次迭代时发生求余运算。没有它,CPU 使用率几乎肯定会大大降低(尽管确切的数字可能在很大程度上取决于硬件——例如,如果你将输出写入磁盘,磁盘的持续带宽将是控制因素)。

【讨论】:

  • 经常是这样,但是这个程序几乎没有输出任何东西。
  • @dspeyer:这并没有改变它本质上所有只是写输出的事实。
  • 基本上它所做的只是算术并决定写输出。
  • @dspeyer 我怀疑输出量不相关 - 这是必须写入 cout 每个循环的开销与 CPU 必须做的极少工作(几个条件和一个计数器)递减)。
  • @dspeyer:显然不是,否则 OP 不会问他提出的问题。仅出于一种可能性,标准输出不必是行缓冲的——它可以是非缓冲的,在这种情况下,你对它如何工作的概念从头到尾都是 100% 错误的。
【解决方案2】:

因为您正在通过 cout 进行阻塞 I/O 调用。去掉 cout 语句会消耗更多的cpu。

每当一个线程在 I/O 操作完成时被阻塞,包括等待控制台打印的 stdout,线程就处于阻塞状态。因此,在阻塞操作完成之前,该线程上没有 CPU 时间。标准输出、内核和控制台都提供了一点缓冲来防止 I/O 阻塞,但最终写得足够快的程序会超过提供的缓冲。

注意。在 Windows 上,这个程序(删除了 cout 打印语句)最多只能使用一个 CPU 核心。如果您使用的是四核,则它只会消耗 Windows 任务管理器上报告的 25% 的 CPU。

【讨论】:

  • 我没有投反对票,但可能投反对票的人想要更多地解释为什么 I/O 调用等于减少 CPU 使用率。这对大多数人来说可能很明显,但对 OP 来说可能不是。
  • 我投了反对票。请参阅有关其他(大致等效)答案的讨论。当您实际运行程序时,这些 cout 调用不会阻塞——它们只是填满进程内的缓冲区。
  • @dspeyer 在我看来,缓冲对性能的影响取决于硬件,可以想象花在 cout(无论是缓冲还是实际输出)上的时间比执行算术要多。
  • 我根据自己编写代码强制cpu使用的真实经验回答了这个问题。虽然内核和 C-Runtime 为所有 I/O 操作提供了一些缓冲,但如果您的写入速度快于控制台显示的速度,您将阻止写入标准输出。因此,阻塞 I/O 调用隐式地使线程脱离运行状态并进入阻塞状态。 CPU 不会在阻塞的线程上花费周期。因此,程序在不需要进行任何 I/O 调用时会消耗更多的 CPU。
猜你喜欢
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
相关资源
最近更新 更多