我正在尝试优化我的程序核心中的一些算法,我想知道硬件的哪个部分真正“减慢”了一切。
当涉及到编程时,硬件中最重要的两个部分可能是CPU和RAM (以及CPU的高速缓冲存储器?)。但是当涉及到性能时,它们如何一起发挥作用呢?
考虑下面这段代码:
std::vector<int> vec;
for(int count = 0; count < 100000; count++)
{
vec.push_back(count);
}在这种情况下,真正使算法变慢的部分是内存写入RAM的速度(?)。CPU的速度几乎不会对代码的执行时间产生任何影响,因为没有太多要计算的东西,对吧?
但是现在,考虑这段代码:
std::vector<int> vec;
for(int count = 0; count < 100000; count++)
{
vec.push_back(count/10/10/10/10);
}在这种情况下,在插入列表(在RAM上)之前(在CPU上)执行几个算术运算。在这种情况下会有很大的性能影响吗?CPU必须首先计算结果,然后才能将结果写入RAM,所以它肯定会更慢,对吧?
如果这是正确的,那么(据我所知)真正减慢程序速度的是可以写入RAM的速度,而不是CPU的速度,对吧?因为即使有一个更复杂的代码块,它也将始终采用以下形式:
//calculate something and write it to the RAM
int something = calculateSomething();总是会有算术运算,以及内存分配。但是当我查看任务管理器时,我很少看到CPU在100 %地工作--它的结论是肯定有另一个部分减慢了整个过程。
言归正传:在优化算法时,我必须考虑的最重要的事情是什么?分配更少的内存并更频繁地重新计算值,这会增加CPU工作并减少内存分配-还是只计算一次值并将其写入内存?什么会给我的算法带来更多的性能呢?今天的现代硬件中,有哪些部分真正能让代码变得像现在这样快?
已经提前感谢了。
发布于 2014-02-26 17:19:46
在这种情况下,真正减慢算法的部分是内存写入内存的速度(?)。
不,真正降低算法速度的不是硬件,而是C++向量的实现,它严重依赖于动态内存分配。它将不得不在该循环中一遍又一遍地调整向量的大小。此外,它还会导致堆碎片。所有这些都将成为主要的瓶颈。
如果您使用普通的"C风格“数组,瓶颈可能是CPU或RAM访问时间。这取决于代码运行在什么硬件上。数据缓存内存不太可能有任何帮助,因为您不会在写入数据后立即使用它。
在这种情况下,在插入到列表之前(在CPU上)执行几个算术运算
不,编译器已经将您的代码转换为count/10000。所以只有一条CPU除法指令。在32位或更大的CPU上,它不会对性能产生很大影响。在8位CPU上,这将导致严重的性能下降,因为它不太可能以有效的方式对大数执行除法。
如果此设置正确,则返回
正如你从上面看到的,大部分都不是。
,但我很少看到CPU在100 %地工作,当查看任务管理器时-它的结论是必须有另一个部分放慢了整个过程。
在PC上,有一个操作系统在后台运行。因此,除了在操作系统之上运行的应用程序之外,几乎总会有一些东西被执行。调度和物理CPU核心的数量也将决定使用了多少%的CPU。当然,每种硬件都起到了作用,不仅是RAM,还有HD访问时间。
在优化算法时,我必须考虑的最重要的事情是什么?
最重要的是要问自己以下问题:
在没有特定硬件的情况下手动优化代码是没有任何意义的。
和今天现代硬件中哪些部分真正使代码变得像现在这样快?
现代硬件通常速度快得离谱……在PC的情况下,任何硬盘驱动器访问都可能是硬件瓶颈。但是,大多数真正减慢代码速度的东西都是软件。程序中的数据混洗和嵌套循环。应用程序使用的夸张的库和各种运行时垃圾。令人难以置信的缓慢的桌面操作系统,同时运行数百个其他程序。诸若此类。
发布于 2014-02-26 17:10:54
即使使用今天的硬件,也可以在一定程度上估计一些事情:算术操作的性能在某种程度上是可以预测的,您可以将一组操作所需的时间计算为单个操作所需时间的总和。粗略地说,高达两倍左右。不幸的是,对于大多数其他操作,这是不可能的。从内存中读取值可能需要1到200个时钟周期。条件跳转的数字是相似的,这取决于分支预测和跳转到的代码的缓存状态。由于这些操作通常会占用大部分性能,因此您很少仅通过查看代码就能猜到瓶颈。使用分析器并准备好迎接一些惊喜,计算平方根可能比从内存中读取结果更快。O(n^2)算法可以比O(n)算法更快。在某些情况下,如果编译器能够证明结果保持不变,它甚至可以将一个转换为另一个。
发布于 2014-02-26 16:19:16
无论您在想什么,类似的事情可能不会在后端发生。现在的编译器已经足够智能,可以尽可能地优化你的程序。因此,如果任何其他程序逻辑不变,您的想法(count/10/10/10/10)将通过(count/10000)进行优化。
我在你的代码中发现的另一件事是:如果你已经知道向量的大小,那么首先分配它,这可能会提高你的性能。至于每次寻找新的位置来存储数据,增加了不必要的计算。
另一种情况虽然CPU速度远高于内存,但您不能只说问题出在内存而不是CPU。分析一下你的代码,找出真正的瓶颈在哪里。
https://stackoverflow.com/questions/22035033
复制相似问题