Search code examples
c++carraysoptimizationhardcode

Is there any performance difference between accessing a hardcode array and a run time initialization array?


For example, I want to create a square root table using array SQRT[i] to optimize a game, but I don't know if there is a performance difference between the following initialization when accessing the value of SQRT[i]:

  1. Hardcode array

    int SQRT[]={0,1,1,1,2,2,2,2,2,3,3,.......255,255,255}
    
  2. Generate value at run time

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

Some example of accessing them:

    if(SQRT[a*a+b*b]>something)
    ...

I'm not clear if the program stores or accesses a hard-code array in a different way, also I don't know if the compiler would optimize the hard-code array to speed up the access time, is there performance differences between them when accessing the array?


Solution

  • First, you should do the hard-coded array right:

    static const int SQRT[]={0,1,1,1,2,2,2,2,2,3,3,.......255,255,255};
    

    (also using uint8_t instead of int is probably better, so as to reduce the size of the array and making it more cache-friendly)

    Doing this has one big advantage over the alternative: the compiler can easily check that the contents of the array cannot be changed.

    Without this, the compiler has to be paranoid -- every function call might change the contents of SQRT, and every pointer could potentially be pointing into SQRT and thus any write through an int* or char* might be modifying the array. If the compiler cannot prove this doesn't happen, then that puts limits on the kinds of optimizations it can do, which in some cases could show a performance impact.

    Another potential advantage is the ability to resolve things involving constants at compile-time.

    If needed, you may be able to help the compiler figure things out with clever use of __restrict__.

    In modern C++ you can get the best of both worlds; it should be possible (and in a reasonable way) to write code that would run at compile time to initialize SQRT as a constexpr. That would best be asked a new question, though.