den*_*art 3 c# performance loops
我对这个新手问题很感兴趣。
比如我们有两种情况:
我有一个具有两个功能的任意循环。(While或For无所谓)。
for (int i = 0; i < 1000; i++)
{
Function_1();
Function_2();
}
Run Code Online (Sandbox Code Playgroud)我有两个循环,每个循环一个动作。
for (int i = 0; i < 1000; i++)
{
Function_1();
}
for (int i = 0; i < 1000; i++)
{
Function_2();
}
Run Code Online (Sandbox Code Playgroud)我知道首先会更快地工作。
但是这两种情况在性能速度上有什么区别呢?(百分比)
如果最大循环数会增加,性能会降低多少?
在这种情况下,什么(处理器或 RAM)会承受更大的负载?
从纯理论的角度来看,两者之间没有区别。无论哪种方式,都是 O(N),这就是结束。
从更实际的角度来看,缓存可以大大改变这个简单的答案。一个可以比另一个更有效地使用缓存。这会不会一定是你已经证明,虽然第一个。
在真正的(现代)计算机上,它基本上可以解决哪个更有效地使用缓存的问题。
反过来,这取决于每个Function_1和使用的内存类型Function_2。如果Function_1 和Function_2 都涉及执行相当多的代码,因此它们中的每一个都适合L1 指令缓存,但它们一起不会,那么第二个版本可能会更快。在这种情况下,第一个版本(在两个函数之间交替)每次执行时都必须从主内存加载每个函数,因此您从主内存加载代码约 2000 次。对于第二个,您从内存中加载 Function_1 的代码一次,从缓存中执行 1000 次,然后对 Function_2 执行相同的操作。总共从主内存加载 2 次。
另一方面,我们假设Function_1 和 Function_2的代码都可以放入指令缓存中,但是 Function_1 和 Function_2 都对相同的数据进行操作,并且该数据的总数太大而无法放入数据缓存中。
这通常会逆转这种情况:在数据块上执行 Function_1,然后在同一数据块上执行 Function_2 只会从内存中加载该数据一次,然后对其进行所有必要的计算,然后加载下一个数据块,等等。每个数据块仅从主存储器加载一次。
在这种情况下,您的代码的第二个版本可能会慢大约 2 倍——它将加载一块内存并在其上执行 Function_1。然后它将加载第二个内存块,并在其上执行 Function_1,依此类推。一旦使用 Function_1 处理了所有内存,它将返回并加载所有相同的内存块以在它们上执行 Function_2。
有一个完整的研究领域,例如缓存感知和缓存遗忘算法,以帮助为您这样的情况做出明智的选择。缓存感知排序基于上述模型(更详细的版本),选择如何组织计算以适应缓存组织。缓存遗忘算法的目标是相对通用的缓存模型,并且几乎不管特定缓存的组织方式如何都提供良好的性能。