所以我正在运行一个控制台项目,但是当代码运行时我在任务管理器中看到只使用了5%(2.8 GHz)的Cpu,当然我并不确定cpu如何分配处理能力窗户开始。但是对于未来的更多信息,我想知道我是否有一个性能要求高的代码,我需要更快的答案,我将如何做到这一点? 如果你想知道,这是代码:
#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char *a, int l, int r)
{
int i;
if (l == r)
cout << a << endl;
else
{
for (i = l; i <= r; i++)
{
swap((a + l), (a + i));
permute(a, l + 1, r);
swap((a + l), (a + i));
}
}
}
int main()
{
char Short[] = "ABCD";
int n1 = strlen(Short);
char Long[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n2 = strlen(Long);
while(true)
{
cout << "Would you like to see the permutions of only a) ABCD or b) the whole alphabet?!\n(please enter a or b): ";
char input;
cin >> input;
if (input == 'a')
{
cout << "The permutions of ABCD:\n";
permute(Short, 0, n1 - 1);
cout << "-----------------------------------";
}
else if (input == 'b')
{
cout << "The permutions of Alphabet:\n";
permute(Long, 0, n2 - 1);
cout << "-----------------------------------";
}
else
{
cout << "ERROR! : Enter either a or b.\n";
}
}
}
我发现博客中的代码显示“ABCD”作为攻击的一部分,但我也将它用于整个字母表,我想知道这种用法是否有办法让代码使用更多cpu?(它的时间比我预期的要长很多)
答案 0 :(得分:4)
学习如何有效地优化代码对于经验丰富的编码人员来说是一项重大挑战,并且有大量关于该主题的书籍,文章和演示文稿。因此,完整的处理远远超出Stack Overflow问题的范围。
那就是说,这里有一些原则:
与此相关,请务必将您的实施与“&#39; stock&#39;算法尽可能。例如,与使用
std::random_shuffle
标题中的C ++ 11<random>
相比,您应该看到实现的执行情况。
首先优化编译器设置。调试版本永远不会很快,并且它们不应该是。使用inline
可以提供帮助,但只有在编译器实际执行内联优化时才会发生。对于Visual C ++,您可以尝试许多不同的优化设置,但请记住,存在权衡因此/Ox
(最大优化)可能并不总是正确的选择,这就是为什么大多数模板默认为{{ 1}}(最大化速度)。在某些情况下,/O2
(最小化空间)实际上更好。
始终在优化之前和之后衡量效果。现代无序CPU是复杂的系统,他们并不总是做您认为他们正在做的事情。在许多情况下,由于各种流水线和微架构效应,代码中的教科书优化实际上比原始代码更糟糕。唯一可以确定的方法是使用一个好的分析器,拥有可靠的测试用例,并测量任何优化工作的影响。如果它平均比以前慢,那么恢复到未经优化的&#39;版本并尝试别的。
关注热点的优化。这就是所谓的80/20&#39;规则。在许多应用程序中,绝大多数代码很少运行,因此只有少数应用程序实际上花费了足够的时间来进行优化。
作为此规则的必然结果,让所有代码使用效率极低的反模式可能会严重影响整个应用程序的基准性能。出于这个原因,一般都应该知道如何编写好的代码。 80/20规则的要点是在有限的时间内优化影响最大的领域而不是程序员认为重要的领域。
所有这一切,在你的情况下,这一切都不重要。绝大部分CPU时间仅用于创建流程和处理序列化输入和输出。当处理4或26的/O1
时,算法的糟糕程度和好处并不重要。换句话说,n
极不可能是您的计划的热点&#39;}除非你正在使用数以万计的角色。
答案 1 :(得分:2)
注意:是的,我过分简化了这个主题,但我很担心 没有这种基本的理解,更高级的主题将会 实际上会导致一些灾难性的程序设计。
也许我错过了一些东西,但似乎也存在对CPU和效率之间关系的误解。
您的程序有N条指令,CPU将以相对相同的速度处理这N条指令(3.56 GHz每秒约35.6亿条指令)。这是相同的(或多或少),无论你是否得到&#34; 5%&#34;或&#34; 25%&#34;从单个程序中使用CPU。 (我稍后会解释这个百分比。)
获得更快&#34;的唯一方法正如erip所说,在处理器使用方面,采用并行计算技术,简而言之,它采用多个CPU来完成任务。
如果您将其视为装配线,则您的一名工人一次只能处理一个小部件。如果你的一小部分小部件占用了他5%的时间,这意味着为了逐个处理你的所有小部件,他使用了5%的时间,而其他95%则不需要批量(并且他可能会将其用于其他人分配给他的其他批次。)
他不能一次处理多个小部件,因此他和你的批处理一样快。您可以通过让他在两种不同类型的小部件之间切换来使事情看起来更快,而不是在批次B开始之前完成所有批次A,但最终处理两个批次仍然需要相同的时间
大规模例外:如果他将100%的时间花在别人的小工具上,那么你真的不得不冷静下来。这不是你可以做的事情。
但是,如果您将另一个工作人员添加到该装配线,他们可以在相同的时间内处理两次(大致)小部件,因为您一次处理两个小部件。当我们说你有一个&#34;四核处理器&#34;时,这基本上意味着你有四个工作人员(字面上是4个CPU)。每个人只能一次处理一条指令,但通过为一批小部件分配多个指令,你可以更快地完成它。
所有这些都说,必须记住那些CPU正在做很多事 - 它们运行整个计算机。您希望尝试尽可能地保持 down 的百分比,这样您的程序在任何支持的计算机上都能快速响应。毕竟,并非所有用户都拥有3.46 GHz四核机器。
答案 2 :(得分:1)
此程序未使用所有可用CPU带宽的原因当然是因为它为每个排列向屏幕发出一次排列结果。这将导致在cout
的实现中阻止I / O.
如果你想要100%的cpu使用,你想要将计算与I / O分开。在这种情况下,您需要:
a)存储结果以供以后输出,或
b)跨线程边界传递结果(由于获取互斥锁和同步缓存的成本,本身会产生效率成本),或者
c)上述的组合(批处理结果并通过线程边界进行通信)
为了快速检查,您可以删除所有cout
次呼叫的注释,并查看您获得的CPU使用量(如上所述,它将接近100%除以计算机上的CPU数量)。