这是一个非常有趣的问题,所以让我设置场景 . 我在国家计算机博物馆工作,我们刚刚设法从1992年开始运行一台Cray Y-MP EL超级计算机,我们真的想看看它有多快!
我们认为最好的方法是编写一个简单的C程序来计算素数,并显示这需要多长时间,然后在快速的现代台式PC上运行程序并比较结果 .
我们很快想出了这个代码来计算素数:
#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的双核笔记本电脑上(The Cray运行UNICOS),工作得很好,CPU使用率达到100%,大约需要10分钟左右 . 当我回到家时,我决定在我的六核现代游戏PC上试用它,这就是我们第一个问题 .
我首先调整了在Windows上运行的代码,因为这是游戏PC正在使用的,但很遗憾发现这个过程只获得了大约15%的CPU功率 . 我认为Windows必须是Windows,因此我启动了Ubuntu的Live CD,认为Ubuntu将允许该进程以其早期在我的笔记本电脑上完成的全部潜力运行 .
但是我只有5%的使用率!所以我的问题是,我怎样才能使程序在Windows 7或Linux上以100%的CPU利用率在我的游戏机上运行?另一件很棒但不必要的事情是,最终产品可以是一个可以在Windows机器上轻松分发和运行的.exe .
非常感谢!
附:当然这个程序并没有真正与Crays 8专业处理器配合使用,这是另外一个问题......如果你对90码Cray超级计算机的优化代码有所了解,那也给我们一个大喊大叫!
9 回答
如果您想要100%CPU,则需要使用1个以上的核心 . 要做到这一点,您需要多个线程 .
Here's a parallel version using OpenMP:
我不得不将限制增加到
1000000
,使我的机器上的时间超过1秒 .Output:
Here's your 100% CPU:
您在多核计算机上运行一个进程 - 因此它只在一个核心上运行 .
解决方案很简单,因为你只是试图固定处理器 - 如果你有N个核心,运行你的程序N次(当然,并行) .
示例
以下是一些并行运行程序
NUM_OF_CORES
次的代码 . 它是POSIXy代码 - 它使用fork
- 所以你应该在Linux下运行它 . 如果我正在阅读关于Cray的内容是正确的,那么在另一个答案中移植此代码可能比OpenMP代码更容易 .输出
生成素数的算法效率很低 . 将它与primegen进行比较,在Pentium II-350上仅需8秒即可生成50847534素数至1000000000 .
要轻松使用所有CPU,您可以在多个线程(进程)中解决embarrassingly parallel problem,例如,计算Mandelbrot set或使用genetic programming to paint Mona Lisa .
另一种方法是为Cray超级计算机采用现有的基准程序并将其移植到现代PC .
您在十六进制核心处理器上获得15%的原因是因为您的代码在100%时使用了1个核心 . 100/6 = 16.67%,使用具有流程调度的移动平均值(您的流程将在正常优先级下运行)可以轻松报告为15% .
因此,为了使用100%的CPU,您需要使用CPU的所有内核 - 为十六进制核心CPU启动6个并行执行代码路径,并且这个规模可以达到您的Cray机器所拥有的许多处理器:)
另外要非常清楚 how 你很难比较两个不同的CPU的性能,特别是两种不同的CPU架构 . 执行任务A可能有利于一个CPU而不是另一个CPU,而执行任务B则可以很容易地相反(因为两个CPU内部可能具有不同的资源并且可能以非常不同的方式执行代码) .
这就是软件与硬件一样使计算机表现最佳的原因 . 对于“超级计算机”来说,这确实也是如此 .
CPU性能的一个衡量指标可能是每秒指令,但是在不同的CPU架构上,指令不会相同 . 另一项措施可能是缓存IO性能,但缓存基础架构也不相同 . 然后,度量可以是每瓦使用的指令数量,作为功率在设计集群计算机时,传递和耗散通常是一个限制因素 .
所以你的第一个问题应该是:哪个性能参数对你很重要?你想测量什么?如果你想看看哪个机器从Quake 4中获得最多的FPS,答案很简单;你的游戏装备会,因为Cray根本无法运行该程序;-)
干杯,斯蒂恩
尝试使用例如OpenMP并行化您的程序 . 它是组成并行程序的一个非常简单有效的框架 .
要在一个核心上快速改进,请删除系统调用以减少上下文切换 . 删除这些行:
第一个特别糟糕,因为它会在每次迭代时产生一个新进程 .
只需尝试Zip和解压缩一个大文件,没有任何重型I / O操作可以使用cpu .
TLDR;接受的答案既低效又不兼容 . 以下算法更快地工作 100x .
MAC上可用的gcc编译器无法运行
omp
. 我不得不安装llvm(brew install llvm )
. 但是我在运行OMP版本时 didn't see CPU idle was going down .这是OMP版本运行时的屏幕截图 .
或者,我使用了基本的POSIX线程,当
nos of thread
=no of cores
= 4(MacBook Pro,2.3 GHz Intel Core i5)时,可以使用任何c编译器和 saw almost entire CPU used up 运行 . 这是程序 -注意整个CPU是如何用完的 -
附: - 如果增加线程数,则实际CPU使用率下降(尝试不使用线程= 20 . )因为系统在上下文切换中使用的时间比实际计算多 .
顺便说一句,我的机器不像@mystical那样强壮(接受的答案) . 但我的基本POSIX线程版本比OMP版本更快 . 结果如下 -
附:将线程负载增加到250万以查看CPU使用情况,因为它在不到一秒的时间内完成 .