这是一个非常有趣的问题,所以让我来设定场景.我在国家计算机博物馆工作,我们刚刚设法让一台克雷Y-MP EL超级计算机从1992年开始运行,我们真的想看看它能跑多快!

我们决定最好的方法是编写一个简单的C程序来计算素数,并显示这样做需要多长时间,然后在一台快速的现代台式电脑上运行该程序并比较结果.

我们很快想出了计算素数的代码:

#include <stdio.h>
#include <time.h>

void main() {
    clock_t start, end;
    double runTime;
    start = clock();
    int i, num = 1, primes = 0;

    while (num <= 1000) { 
        i = 2; 
        while (i <= num) { 
            if(num % i == 0)
                break;
            i++; 
        }
        if (i == num)
            primes++;

        system("clear");
        printf("%d prime numbers calculated\n",primes);
        num++;
    }

    end = clock();
    runTime = (end - start) / (double) CLOCKS_PER_SEC;
    printf("This machine calculated all %d prime numbers under 1000 in %g seconds\n", primes, runTime);
}

它在我们运行Ubuntu的双核笔记本电脑(Cray运行UNICOS)上运行得很好,CPU使用率达到100%,大约需要10分钟左右.当我回到家后,我决定在我的祸不单行核心的现代游戏电脑上试一试,这就是我们得到第一期的地方.

我第一次修改代码,使其在Windows上运行,因为游戏PC使用的是Windows,但我很难过地发现,这个过程只消耗了CPU约15%的电量.我想那一定是Windows即Windows,所以我启动了一张Ubuntu的Live CD,以为Ubuntu会让这个过程像之前在我的笔记本电脑上做的那样,充分发挥其潜力.

然而,我只有5%的使用率!所以我的问题是,我如何调整程序,使其在Windows 7或live Linux中的游戏机上以100%的CPU利用率运行?另一件很好但不必要的事情是,如果最终产品可以是这样的话.可以轻松分发并在Windows计算机上运行的exe.

谢谢!

附注:当然,这个程序并不能真正与CRAYS8专业处理器一起工作,这完全是另一回事了……如果你知道任何关于优化代码以在90年代的Cray超级计算机上工作的知识,也请给我们一个惊喜!

推荐答案

如果你想要100%的CPU,你需要使用一个以上的核心.要做到这一点,需要多个线程.

Here's a parallel version using OpenMP:

我不得不将限制提高到1000000,以使我的机器上的时间超过1秒.

#include <stdio.h>
#include <time.h>
#include <omp.h>

int main() {
    double start, end;
    double runTime;
    start = omp_get_wtime();
    int num = 1,primes = 0;

    int limit = 1000000;

#pragma omp parallel for schedule(dynamic) reduction(+ : primes)
    for (num = 1; num <= limit; num++) { 
        int i = 2; 
        while(i <= num) { 
            if(num % i == 0)
                break;
            i++; 
        }
        if(i == num)
            primes++;
//      printf("%d prime numbers calculated\n",primes);
    }

    end = omp_get_wtime();
    runTime = end - start;
    printf("This machine calculated all %d prime numbers under %d in %g seconds\n",primes,limit,runTime);

    return 0;
}

Output:

这台机器在29.753秒内计算出了1000000以下的78498个素数

Here's your 100% CPU:

在此处输入图像描述

C++相关问答推荐

命名信号量不会像进程之间同步中假设的那样工作

为什么静态说明符为内联函数生成外部定义?

如何使用Python C API实现多线程程序?

使用NameSurname扫描到两个单独的字符串

核心转储文件中出现奇怪的大小变化

使用AVX2的英特尔2022编译器的NaN问题&;/fp:FAST

_泛型控制表达式涉及数组碰撞警告的L值转换错误?

在C++中使用函数指针的正确语法

致命:ThreadSaniizer:在Linux内核6.6+上运行时意外的内存映射

进程在写入管道时挂起

为什么我会收到释放后堆使用错误?

如何在C中使数组变量的值为常量?

#定义SSL_CONNECTION_NO_CONST

将变量或参数打包到 struct /联合中是否会带来意想不到的性能损失?

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

如何在C中定义指向函数的指针并将该指针赋给函数?

强制GCC始终加载常量(即只读),即使启用了优化

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

如何修复数组数据与列标题未对齐的问题?

UEFI 应用程序中的计时器回调仅在 AMI BIOS 中挂起