gpt4 book ai didi

c++ - 指针上的指针 - 性能损失的原因

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:02 24 4
gpt4 key购买 nike

我回答了this question ,并注意到我认为编译器的一种奇怪行为。

我首先编写了这个程序(作为我在那里回答的一部分):

class Vector {
private:
double** ptr;


public:

Vector(double** _ptr): ptr(_ptr) {}

inline double& operator[](const int iIndex) const {
return *ptr[iIndex];
}
};

extern "C" int test(const double a);

int main() {
double a[2] = { 1.0, 2.0 };
Vector va((double**) &a);

double a1 = va[0];
test(a1);

double a2 = va[0];
test(a2);
}

编译时生成两条加载指令:

clang -O3 -S -emit-llvm main.cpp -o main.ll

这可以在 llvm-IR 中看到(也可以在程序集中看到):

    define i32 @main() #0 {    entry:      %a.sroa.0.0.copyload = load double*, double** bitcast ([2 x double]* @_ZZ4mainE1a to double**), align 16      %0 = load double, double* %a.sroa.0.0.copyload, align 8, !tbaa !2      %call1 = tail call i32 @test(double %0)      %1 = load double, double* %a.sroa.0.0.copyload, align 8, !tbaa !2      %call3 = tail call i32 @test(double %1)      ret i32 0    }

I would expect only one load instruction, since no function with side effect on memory has been called, and I didn't link this object to something with side effects. In fact, when reading the program, I just expect two calls to

test(1.0);

因为我的数组在内存中是常量,所有内容都可以正确内联。

为了确定,我用一个简单的指针替换了双指针:

class Vector {
private:
double* ptr;

public:
Vector(double* _ptr): ptr(_ptr) {}

inline double& operator[](const int iIndex) const {
return ptr[iIndex];
}
};

extern "C" int test(const double a);

int main() {
double a[2] = { 1.0, 2.0 };
Vector va(a);

double a1 = va[0];
test(a1);

double a2 = va[0];
test(a2);
}

用同一行编译,我得到了预期的结果:

define i32 @main() #0 {
entry:
%call1 = tail call i32 @test(double 1.000000e+00)
%call3 = tail call i32 @test(double 1.000000e+00)
ret i32 0
}

看起来优化得更好:)

因此我的问题是:

什么原因阻止编译器对第一个代码示例执行相同的内联?那是双指针吗?

最佳答案

错误在这些行中:

double a[2] = { 1.0, 2.0 };
Vector<double> va((double**) &a);

a 是两个 double 组。它衰减double *,但&a不是 double ** . 数组和指针不是同一种动物

事实上你有以下内容:(void *) a == (void *) &a 因为数组的地址是它的第一个元素的地址。

如果你想构建一个指向指针的指针,你必须明确地创建一个真正的指针:

double a[2] = { 1.0, 2.0 };
double *pt = a; // or &(a[0]) ...
Vector<double> va((double**) &pt);

关于c++ - 指针上的指针 - 性能损失的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37323517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com