首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >优化代码- CPU与内存

优化代码- CPU与内存
EN

Stack Overflow用户
提问于 2014-02-26 15:51:34
回答 3查看 2.6K关注 0票数 1

我正在尝试优化我的程序核心中的一些算法,我想知道硬件的哪个部分真正“减慢”了一切。

当涉及到编程时,硬件中最重要的两个部分可能是CPU和RAM (以及CPU的高速缓冲存储器?)。但是当涉及到性能时,它们如何一起发挥作用呢?

考虑下面这段代码:

代码语言:javascript
复制
std::vector<int> vec;
for(int count = 0; count < 100000; count++)
{
    vec.push_back(count);
}

在这种情况下,真正使算法变慢的部分是内存写入RAM的速度(?)。CPU的速度几乎不会对代码的执行时间产生任何影响,因为没有太多要计算的东西,对吧?

但是现在,考虑这段代码:

代码语言:javascript
复制
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的速度,对吧?因为即使有一个更复杂的代码块,它也将始终采用以下形式:

代码语言:javascript
复制
//calculate something and write it to the RAM
int something = calculateSomething();

总是会有算术运算,以及内存分配。但是当我查看任务管理器时,我很少看到CPU在100 %地工作--它的结论是肯定有另一个部分减慢了整个过程。

言归正传:在优化算法时,我必须考虑的最重要的事情是什么?分配更少的内存并更频繁地重新计算值,这会增加CPU工作并减少内存分配-还是只计算一次值并将其写入内存?什么会给我的算法带来更多的性能呢?今天的现代硬件中,有哪些部分真正能让代码变得像现在这样快?

已经提前感谢了。

EN

回答 3

Stack Overflow用户

发布于 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访问时间。

在优化算法时,我必须考虑的最重要的事情是什么?

最重要的是要问自己以下问题:

  • 是否真的需要优化这段代码?你是否发现了一个真正的瓶颈?
  • 你真的知道预处理器和编译器的优化器是如何工作的吗?
  • 你真的知道编译器是如何将C++代码翻译成机器码的吗?
  • 你是否对给定系统有深入的硬件知识,以至于你比为给定硬件制作编译器端口的人更了解硬件?
  • 您是否深入了解CPU的硬件优化功能,如流水线、数据/指令缓存、分支predication?

在没有特定硬件的情况下手动优化代码是没有任何意义的。

和今天现代硬件中哪些部分真正使代码变得像现在这样快?

现代硬件通常速度快得离谱……在PC的情况下,任何硬盘驱动器访问都可能是硬件瓶颈。但是,大多数真正减慢代码速度的东西都是软件。程序中的数据混洗和嵌套循环。应用程序使用的夸张的库和各种运行时垃圾。令人难以置信的缓慢的桌面操作系统,同时运行数百个其他程序。诸若此类。

票数 3
EN

Stack Overflow用户

发布于 2014-02-26 17:10:54

即使使用今天的硬件,也可以在一定程度上估计一些事情:算术操作的性能在某种程度上是可以预测的,您可以将一组操作所需的时间计算为单个操作所需时间的总和。粗略地说,高达两倍左右。不幸的是,对于大多数其他操作,这是不可能的。从内存中读取值可能需要1到200个时钟周期。条件跳转的数字是相似的,这取决于分支预测和跳转到的代码的缓存状态。由于这些操作通常会占用大部分性能,因此您很少仅通过查看代码就能猜到瓶颈。使用分析器并准备好迎接一些惊喜,计算平方根可能比从内存中读取结果更快。O(n^2)算法可以比O(n)算法更快。在某些情况下,如果编译器能够证明结果保持不变,它甚至可以将一个转换为另一个。

票数 2
EN

Stack Overflow用户

发布于 2014-02-26 16:19:16

无论您在想什么,类似的事情可能不会在后端发生。现在的编译器已经足够智能,可以尽可能地优化你的程序。因此,如果任何其他程序逻辑不变,您的想法(count/10/10/10/10)将通过(count/10000)进行优化。

我在你的代码中发现的另一件事是:如果你已经知道向量的大小,那么首先分配它,这可能会提高你的性能。至于每次寻找新的位置来存储数据,增加了不必要的计算。

另一种情况虽然CPU速度远高于内存,但您不能只说问题出在内存而不是CPU。分析一下你的代码,找出真正的瓶颈在哪里。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22035033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档