![]() |
1
25
只有一种方法可以知道,那就是测试和测量 . 您需要找出瓶颈所在(CPU、内存带宽等)。 数组中数据的大小(示例中的int)会影响结果,因为这会影响处理器缓存的使用。通常,您会发现示例2更快,这基本上意味着您的内存带宽是限制因素(示例2将以更有效的方式访问内存)。 |
![]() |
2
9
下面是一些使用vs2005构建的带有时间的代码:
运行这个,后一个版本通常更快。 我试着写一些汇编程序来击败第二个循环,但我的尝试通常比较慢。所以我决定看看编译器生成了什么。下面是为第二个版本的主求和循环生成的优化汇编程序:
以下是寄存器的用法:
这里有一些有趣的事情:
要真正理解为什么这很快,您需要使用英特尔的“vtune性能分析器”来查看CPU和内存的暂停位置,因为这段代码非常违反直觉。 |
![]() |
3
7
理论上,由于缓存优化,第二个应该更快。 缓存进行了优化,可以携带和保存数据块,以便在第一次访问时,您可以将第一个数组的一大块数据放入缓存。在第一个代码中,当您访问第二个数组时,可能需要取出第一个数组的一些数据,因此需要更多的访问。 在实践中,这两种方法将或多或少地花费相同的时间,因为考虑到实际缓存的大小和完全没有数据从缓存中取出的可能性,这是第一种稍好一点的方法。 注意:这听起来很像家庭作业。在实际生活中,对于这些大小,第一个选项将稍微快一点,但这仅适用于此具体示例,嵌套循环、更大的数组或特别是更小的缓存大小将根据顺序对性能产生重大影响。 |
![]() |
4
5
第一个会更快。编译器不需要重复该循环两次。虽然工作不多,但是在增加循环变量和执行检查条件时,某些循环会丢失。 |
![]() |
5
4
对于我(gcc-o3),测量显示第二个版本的速度快了25%,这可以用更有效的内存访问模式来解释(所有内存访问都是彼此接近的,而不是到处都是)。当然,在差异变得显著之前,您需要重复操作数千次。 我还尝试了从数字头中进行std::accumulation,这是实现第二个版本的简单方法,而且比第二个版本快了一点点(可能是由于更易于编译器的循环机制?):
|
![]() |
6
2
第一个会更快,因为您只循环一次从1到10000。 |
![]() |
7
2
C++标准对此一无所知,它是依赖于实现的。看起来您正在尝试提前优化。它不应该困扰你,直到它在你的程序中不是一个瓶颈。如果是这样的话,您应该使用一些分析器来找出在特定平台上哪个分析器更快。
在那之前,我更喜欢第一个变体,因为它看起来更可读(或更好)
|
![]() |
8
2
如果数据类型的大小足够大,不能同时缓存两个变量(例如1),而只能缓存单个变量(示例2),那么第一个示例的代码将比第二个示例的代码慢。 否则,第一个示例的代码将比第二个示例的代码快。 |
![]() |
9
1
第一个可能会更快。内存访问模式将允许(现代)CPU高效地管理缓存(预取),即使在访问两个阵列时也是如此。 如果您的CPU允许它,并且阵列是对齐的,那么速度会快得多:使用SSE3指令一次处理4int。 |
![]() |
10
0
如果你是说
如果
为一些被投票通过的答案提供了思考的食物:在代码的每个版本中执行了多少添加? |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 8 月前 |
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 8 月前 |
![]() |
Bobby · 复合字面值总是左值吗? 8 月前 |
![]() |
9-Pin · C: 嵌套结构的堆栈内存分配 8 月前 |