为什么4维向量比4维std :: array性能更好

时间:2019-02-22 10:08:27

标签: performance c++11

#include <iostream>
#include <vector>
#include <array>
#include <chrono>


#define D1  8
#define D2 16
#define D3 12
#define D4 16

struct my_big_Struct {
    uint64_t data[16] = {0};
};


struct my_vector_class {
    std::vector<std::vector<std::vector<std::vector<struct my_big_Struct>>>> myobj;
    my_vector_class() {
        myobj.resize(D1);
        for (auto i = 0; i < D1; i++) {
            myobj[i].resize(D2);
            for (auto j = 0; j < D2; j++) {
                myobj[i][j].resize(D3);
                for (auto k = 0; k < D3; k++) {
                    myobj[i][j][k].resize(D4);
                }
            }
        }
        for (auto i = 0; i < D1; i++) {
            for (auto j = 0; j < D2; j++) {
                for (auto k = 0; k < D3; k++) {
                    for (auto l = 0; l < D4; l++) {
                        myobj[i][j][k][l].data[0] = rand();
                    }
                }
            }
        }
    }
};

struct my_array_class {
    std::array< std::array < std::array < std::array<struct my_big_Struct, D1>, D2>, D3>, D4> arr;
    my_array_class() {
        for (auto i = 0; i < D1; i++) {
            for (auto j = 0; j < D2; j++) {
                for (auto k = 0; k < D3; k++) {
                    for (auto l = 0; l < D4; l++) {
                        arr[i][j][k][l].data[0] = rand();
                    }
                }
            }
        }
    }
};

#define LOOP_COUNT 1



int main() {
    struct my_vector_class vec;
    struct my_array_class arr;
    uint64_t sum = 0;
    auto start = std::chrono::high_resolution_clock::now();

    for (auto lc = 0; lc < LOOP_COUNT; ++lc) {
        for (auto i = 0; i < D1; i++) {
            for (auto j = 0; j < D2; j++) {
                for (auto k = 0; k < D3; k++) {
                    for (auto l = 0; l < D4; l++) {
                        sum +=vec.myobj[i][j][k][l].data[0];
                    }
                }
            }
        }
    }
    auto stop  = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff = stop-start;
    std::cout << "Elapsed vec " << diff.count() << "\n";
    auto start2 = std::chrono::high_resolution_clock::now();
    for (auto lc = 0; lc < LOOP_COUNT; ++lc) {
        for (auto i = 0; i < D1; i++) {
            for (auto j = 0; j < D2; j++) {
                for (auto k = 0; k < D3; k++) {
                    for (auto l = 0; l < D4; l++) {
                        sum +=arr.arr[i][j][k][l].data[0];
                    }
                }
            }
        }
    }
    auto stop2  = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff2 = stop2-start2;
    std::cout << "Elapsed arr " << diff2.count() << "\n";
    auto start3 = std::chrono::high_resolution_clock::now();
    for (auto lc = 0; lc < LOOP_COUNT; ++lc) {
        for (auto i = 0; i < D1; i++) {
                for (auto j = 0; j < D2; j++) {
                    for (auto k = 0; k < D3; k++) {
                        for (auto l = 0; l < D4; l++) {
                            sum +=vec.myobj[i][j][k][l].data[0];
                        }
                }
            }
        }
    }
    auto stop3  = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff3 = stop3-start3;
    std::cout << "Elapsed vec " << diff3.count() << "\n";
    auto start4 = std::chrono::high_resolution_clock::now();
    for (auto lc = 0; lc < LOOP_COUNT; ++lc) {
        for (auto i = 0; i < D1; i++) {
            for (auto j = 0; j < D2; j++) {
                for (auto k = 0; k < D3; k++) {
                    for (auto l = 0; l < D4; l++) {
                        sum +=arr.arr[i][j][k][l].data[0];
                    }
                }
            }
        }
    }
    auto stop4  = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> diff4 = stop4-start4;
    std::cout << "Elapsed arr " << diff4.count() << "\n";
};

因此,我创建了一个大对象(128B)的4D-矢量和4D数组,并尝试遍历它们两次...为了使缓存变暖效果归零...我始终发现数组版本慢2倍...

gcc-5.2.0 / bin / g ++

g ++ -std = c ++ 11 main.cpp -o vecvsarr ./vecvsarr

Elapsed vec 0.475446
Elapsed arr 0.846845
Elapsed vec 0.441586
Elapsed arr 0.829504

通过添加优化-O3,我得到了一些加速。.但我期望会有显着差异

进行了优化:

Elapsed vec 2.58e-07
Elapsed arr 1.52e-07
Elapsed vec 1.21e-07
Elapsed arr 1.15e-07

1 个答案:

答案 0 :(得分:0)

按照Bob_的建议使用了Godbolt,发现存在启用了优化的循环优化。启用打印并运行相当可观的速度后,其速度提高了2倍。

Elapsed vec 15.7311 
Elapsed arr 7.78011 
Elapsed vec 14.7511 
Elapsed arr 7.24151 
Sum 2486663010270848384