Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用新位置,代码运行速度更快_C++_Performance_Gcc_Compiler Optimization - Fatal编程技术网

C++ 使用新位置,代码运行速度更快

C++ 使用新位置,代码运行速度更快,c++,performance,gcc,compiler-optimization,C++,Performance,Gcc,Compiler Optimization,我上了这门课 方法1: typedef float v4sf __attribute__ (vector_size(16)) class Unit { public: Unit(int num) { u = new float[num]; v = new float[num]; } void update() { for(int i =0 ; i < num; i+=4) {

我上了这门课

方法1:

typedef float v4sf __attribute__ (vector_size(16))

class Unit
{
    public:
    Unit(int num)
    {
        u = new float[num];
        v = new float[num];
    }
    void update()
    {
        for(int i =0 ; i < num; i+=4)
        {
            *(v4sf*)&u[i] = *(v4sf*)&v[i] + *(v4sf*)&t[i];
            //many other equations
        }
    }
    float*u,*v,*t; //and many other variables
}
然而,方法2快2倍。为什么呢

大约有12个浮点变量,num为500K。update()被调用
1k
次。速度不影响内存分配。我这样测量速度:

double start = getTime();
for( int i = 0; i < 1000; i++)
{
   unit->update();
}
double end = getTime();
cout<<end - start;
double start=getTime();
对于(int i=0;i<1000;i++)
{
单元->更新();
}
double-end=getTime();

cout正常新建实际上是分配+构造,而放置新建只是构造。
因此,分配+2构造自然比分配+构造+分配+构造快。

此外,整数类型的构造是nop,因此在您的例子中,它是2次分配与1次分配。

我假设在方法2中,编译器能够识别u和v的地址在调用之间不会改变,因此,将for循环中方程式中使用的一些指针保留在寄存器中。

可能是因为“方法2”有一个错误——所有变量
u
v
t
都位于内存中完全相同的位置(您将相同的地址传递给新位置)

编辑:现在您不需要……;)


如果没有分析,很难猜测,但它可能与默认分配器有关。如果在第一种方法中,每个变量都有单独的new调用,则不能保证这些变量将被分配到彼此接近的地址。另一方面,在第二种方法中,你要确保它们尽可能靠近对方。这将最大限度地提高缓存利用率并限制缓存未命中。

分解计时并查看构造函数中的哪个部分与更新中的哪个部分是非常有用的


由于
update
没有更改,因此唯一会影响其计时的是缓存对数据的影响。这足以解释2倍的差异。

您能显示方法2的实际代码吗?处理器是什么?我有一种强烈的感觉,你可能会遇到类似的情况:u和v现在是一样的。我认为应该使用v=new(buffer+sizeof(float)*num)对方法3进行基准测试会很有趣:使用
std::vector
什么是
num
?它大吗?特别是在50k-100k的数量级上,数据缓存命中/未命中率可能要高得多。对不起,代码有误。所有变量都位于不同且正确的位置。@VivekG这是否意味着复制和粘贴时出错(这就是您所做的,对吗?您没有让我们在错误的代码中四处寻找问题,是吗?)或是原始代码中的错误,现在会产生不同的结果?不,对不起,问题是真的。我没有复制粘贴代码,因为它是专有的。我在这里输入代码时犯了一个错误。@RMF的意思是:请不要发布与您观察到的代码“相似”的代码,并声称它会有一些行为,而不需要自己尝试更简单的发布代码。在谈论性能时尤其重要!
double start = getTime();
for( int i = 0; i < 1000; i++)
{
   unit->update();
}
double end = getTime();
cout<<end - start;