![]() |
1
5
我可以看到三个变量(即使在一段看似简单的代码中):
|
![]() |
2
10
测量就是知道。 |
![]() |
3
5
另一方面,这完全取决于
正如你所说:这要看情况。 |
![]() |
4
2
你的问题还不够清楚,不能给出一个稍微准确的答案,但我想我明白你的意思。您正在迭代的数据足够大,以至于在到达末尾之前,您将开始逐出数据,以便您在第二次(第二个循环)中对其进行迭代时,必须再次读取一些(如果不是全部的话)。 如果两个循环连接在一起,以便为第一个操作提取每个元素/块,然后为第二个操作已经在缓存中,那么无论数据相对于缓存有多大,如果不是所有的第二个操作都将从缓存中获取数据,则大多数第二个操作都将从缓存中获取数据。 各种各样的事情,比如缓存的性质,循环被数据逐出,然后被提取,逐出数据可能会导致第二个操作的一些遗漏。在一台装有操作系统的pc机上,其他程序获取时间片时,会发生大量的逐出操作。但假设一个理想世界,对数据索引i的第一个操作将从内存中获取数据,第二个操作将从缓存中获取数据。 优化缓存充其量也很困难。我经常演示,即使使用嵌入式系统,也没有中断、单个任务、相同的源代码。通过简单地更改编译器优化选项、更改编译器(无论是编译器品牌还是编译器版本),执行时间/性能都会发生巨大变化,gcc2.x vs 3.x vs 4.x(顺便说一句,gcc不一定能用更新的版本生成更快的代码)(而且一个编译器在很多目标上都很好,但在任何一个特定目标上都不是很好)。相同的代码不同的编译器或选项可以改变执行时间几倍,3倍快,10倍快,等等。一旦你进入测试有或没有缓存,它变得更加有趣。在启动代码中添加一个nop,这样整个程序就可以在内存中移动一条指令,而缓存线现在会在不同的地方命中。相同的编译器相同的代码。用两个nop,三个nop,等等重复这个步骤。同样的编译器,同样的代码,你可以看到百分之十的差异(对于我那天用那个编译器在那个目标上运行的测试),好的和坏的。这并不意味着你不能调整缓存,它只是意味着试图找出你的调整是帮助还是伤害可能是困难的。正常的答案是“计时看”,但这已经不起作用了,你可能会在你的电脑上得到很好的结果,那一天与该程序的编译器。但是明天在你的电脑上或者任何一天在别人的电脑上你可能会让事情变慢而不是变快。你需要理解为什么这个或那个改变使它更快,也许它与你的代码无关,你的电子邮件程序可能在一个测试期间在后台下载了很多邮件,而不是在另一个测试期间。 假设我正确地理解了你的问题,我认为单循环通常更快。 |
![]() |
5
1
把循环分成小块是个好主意。。它可以大大提高缓存命中率,并对性能产生很大影响。。。 从你的例子来看:
我要么把两个回路融合成一个回路,就像这样:
当然,如果这是不可能的,请执行称为循环平铺的优化:
将循环分解成更小的块,然后一个接一个地执行它们,这将非常有帮助。诀窍是将工作内存集限制在一级缓存的大小以下。我的目标是缓存大小的一半,这样在这两者之间执行的其他线程就不会把我的缓存搞得一团糟。。 |
![]() |
6
0
这看起来像是编译器可以为您优化的东西,所以不要试图自己去弄清楚它并使之快速,而是使用任何方法使您的代码更清晰易读。如果您真的必须知道,请计时应用程序使用的输入大小和计算类型的两种方法(尝试现在的代码,但要多次重复计算并禁用优化)。 |
![]() |
7
0
如果我在代码中遇到两个循环的版本,没有解释性的注释,我会想为什么程序员会这样做,并且可能会认为该技术的质量可疑,而一个单循环的版本不会令人惊讶,注释或不注释。 但是,如果我遇到了双循环版本以及类似“我使用双循环是因为它在CPU Y上的缓存中运行速度快了X%”这样的注释,至少我不再对代码感到困惑,尽管我仍然怀疑它是否正确,是否适用于其他机器。 |
![]() |
giantjenga · 优化整数向量到二进制向量的转换 8 月前 |
![]() |
Daniel Lobo · 使用约束进行优化 8 月前 |
![]() |
Sergio · python中大量数字的乘法 1 年前 |
![]() |
Sergey Dev · 临时表与表变量 1 年前 |
![]() |
John · 减少C中的内存消耗++ 1 年前 |