在C ++中慢慢写入数组

时间:2010-02-10 02:32:17

标签: c++ optimization

我只是想知道这是否是C ++中的预期行为。下面的代码大约在0.001毫秒运行:

for(int l=0;l<100000;l++){
        int total=0;
        for( int i = 0; i < num_elements; i++) 
        {
            total+=i;
        }
    }

但是如果将结果写入数组,则执行时间最多可达15毫秒:

int *values=(int*)malloc(sizeof(int)*100000);
        for(int l=0;l<100000;l++){
            int total=0;
            for( unsigned int i = 0; i < num_elements; i++) 
            {
                total+=i;
            }
            values[l]=total;
        }

我可以理解写入数组需要时间,但时间是否成比例?

为每个人欢呼

4 个答案:

答案 0 :(得分:11)

第一个例子可以仅使用CPU寄存器来实现。这些可以每秒访问数十亿次。第二个例子使用了如此多的内存,它确实溢出了L1和可能的L2缓存(取决于CPU模型)。那会慢一些。然而,15 ms / 100.000写入每次写入1.5 ns - 667 Mhz有效。那是慢。

答案 1 :(得分:10)

看起来编译器在第一种情况下完全优化了循环。

循环的总效果是无操作,因此编译器只是删除它。

答案 2 :(得分:3)

这很简单。 在第一种情况下,您只有3个变量,可以很容易地存储在GPR(通用寄存器)中,但这并不意味着它们一直存在,但它们可能在L1高速缓存中,这意味着它们可以可以非常快速地访问。

在第二种情况下,您有超过100k的变量,并且您需要大约400kB来存储它们。这对于寄存器和L1高速缓冲存储器来说是非常有用的。在最好的情况下,它可能在L2缓存中,但可能并非所有这些都在L2中。如果没有注册的东西,L1,L2(我假设您的处理器没有L3),这意味着您需要在RAM中搜索它,并且需要花费更多的时间。

答案 3 :(得分:1)

我怀疑你所看到的是virtual memory和可能的分页的影响。 malloc调用将分配一个相当大的内存块,可能由许多虚拟页面表示。每个页面都分别链接到进程内存。

您可能还在测量调用malloc的费用,具体取决于您为循环计时的方式。在任何一种情况下,性能都会对编译器优化选项,线程选项,编译器版本,运行时版本以及其他任何内容非常敏感。您无法安全地假设成本与分配的大小成线性关系。您唯一可以做的就是测量它并找出一旦被证明是一个问题,如何最好地优化