访问硬编码阵列和运行时初始化阵列之间有任何性能差异吗?

ggr*_*grr 5 c c++ arrays optimization hardcode

例如,我想使用数组SQRT [i]创建一个平方根表来优化游戏,但我不知道在访问SQRT [i]的值时,以下初始化之间是否存在性能差异:

  1. 硬编码阵列

    int SQRT[]={0,1,1,1,2,2,2,2,2,3,3,.......255,255,255}
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在运行时生成值

    int SQRT[65536];
    int main(){
        for(int i=0;i<65536;i++){
            SQRT[i]=sqrt(i);
        }
        //other code
        return 0;
    }
    
    Run Code Online (Sandbox Code Playgroud)

访问它们的一些示例:

    if(SQRT[a*a+b*b]>something)
    ...
Run Code Online (Sandbox Code Playgroud)

我不清楚程序是否以不同的方式存储或访问硬代码阵列,我也不知道编译器是否会优化硬代码阵列以加快访问时间,它们之间是否存在性能差异访问阵列时?

小智 4

首先,您应该正确执行硬编码数组:

static const int SQRT[]={0,1,1,1,2,2,2,2,2,3,3,.......255,255,255};
Run Code Online (Sandbox Code Playgroud)

(也使用uint8_t代替int可能更好,以便减少数组的大小并使其对缓存更友好)

与其他方法相比,这样做有一个很大的优点:编译器可以轻松检查数组的内容是否无法更改。

如果没有这个,编译器就会变得偏执——每个函数调用都可能改变 的内容SQRT,并且每个指针都可能指向SQRT,因此任何通过int*or 的写入char*都可能会修改数组。如果编译器无法证明这种情况不会发生,那么就会限制它可以执行的优化类型,这在某些情况下可能会显示出性能影响。

另一个潜在的优点是能够在编译时解决涉及常量的问题。

如果需要,您也许可以通过巧妙地使用__restrict__.

在现代 C++ 中,您可以两全其美;应该可以(并且以合理的方式)编写在编译时运行以初始化SQRTconstexpr. 不过,最好提出一个新问题。

  • @Bobby:...而 `char` 很可能是 8 位 *signed* 类型,这意味着它的最大值为 `127`。除此之外,当您拥有明确指示您的位宽度要求的类型时,使用它们是一个好习惯。 (2认同)