代码之家  ›  专栏  ›  技术社区  ›  Ljdawson

C++中数组的慢速写入

  •  5
  • Ljdawson  · 技术社区  · 16 年前

    我只是想知道这是否是C++中的预期行为。以下代码在0.001 ms左右运行:

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

    但是,如果将结果写入数组,则执行时间最长为15 ms:

    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 回复  |  直到 16 年前
        1
  •  11
  •   MSalters    16 年前

    第一个例子可以只用CPU寄存器来实现。每秒可以访问数十亿次。第二个例子使用了太多的内存,它肯定会溢出l1和l2缓存(取决于CPU模型)。那会更慢。尽管如此,15 ms/100.000的写入速度达到1.5 ns/write-667兆赫。那是 不 慢。

        2
  •  10
  •   Anon.    16 年前

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

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

        3
  •  3
  •   Tomek Tarczynski    16 年前

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

    在第二种情况下,您有超过100K个变量,并且您需要大约400KB来存储它们。对于寄存器和一级缓存来说,这是非常有限的。在最好的情况下,它可能在二级缓存内存中,但可能不是所有缓存都在二级缓存中。如果寄存器l1、l2(我假设处理器没有l3)中没有某些内容,这意味着您需要在RAM中搜索它,这需要花费更多的时间。

        4
  •  1
  •   D.Shawley    16 年前

    我怀疑你看到的是 virtual memory 可能还有寻呼。这个 malloc 调用将分配一个相当大的内存块,该内存块可能由多个虚拟页表示。每个页面分别链接到进程内存中。

    你也可能在衡量打电话的成本 马洛克 取决于循环的计时方式。无论是哪种情况,性能都将对编译器优化选项、线程选项、编译器版本、运行时版本以及其他任何内容非常敏感。您不能安全地假设成本与分配的大小是线性的。你唯一能做的就是测量它并找出最佳的优化方法。 一旦它被证明是一个问题 .