C ++数据访问基准

时间:2017-05-19 11:33:24

标签: c++ benchmarking

m writing simple benchmark on C++ to compare the execution time of data access on different platforms.And I得到了奇怪的结果。我测量顺序订单访问和间接订单访问的时间。为此,我只是以两种不同的方式将一个数组数据复制到另一个。代码和结果如下。 我得到的时间是模棱两可的。对int数据类型的评估显示,顺序访问更快(可以)。但是对于float和double类型,它恰恰相反(参见下面的时间结果)。也许我的基准测试错误或者我没有考虑到一些陷阱?或者您可以建议一些基准工具来比较不同数据类型的数据访问或简单操作性能吗?

template<typename T>
std::chrono::nanoseconds::rep PerformanceMeter<T>::testDataAccessArr()
{
    std::chrono::nanoseconds::rep totalSequential = 0;

    T* arrDataIn = new T[k_SIZE];
    T* arrDataOut = new T[k_SIZE];

    std::generate_n(arrDataIn, k_SIZE, DataProcess<T>::valueGenerator);
    DataProcess<T>::clearCache();

    std::chrono::nanoseconds::rep timeSequential = measure::ns(copySequentialArr, arrDataIn, arrDataOut, k_SIZE);

    std::cout << "Sequential order access:\t" << timePrint(timeSequential) << "\t";
    std::cout.flush();

    std::chrono::nanoseconds::rep totalIndirection = 0;
    T** pointers = new T*[k_SIZE];
    T** pointersOut = new T*[k_SIZE];
    for (size_t i = 0; i < k_SIZE; ++i)
    {
        pointers[i] = &arrDataIn[i];
        pointersOut[i] = &arrDataOut[i];
    }

    std::generate_n(arrDataIn, k_SIZE, DataProcess<T>::valueGenerator);
    std::generate_n(arrDataOut, k_SIZE, DataProcess<T>::valueGenerator);

    DataProcess<T>::clearCache();

    totalIndirection = measure::ns(copyIndirectionArr, pointers, pointersOut, k_SIZE);

    std::cout << std::endl << "Indirection order access:\t" << timePrint(totalIndirection) << std::endl;
    std::cout.flush();

    delete[] arrDataIn;
    delete[] arrDataOut;
    delete[] pointers;
    delete[] pointersOut;

    return timeSequential;
}

template <typename T>
void PerformanceMeter<T>::copySequentialArr(const T* dataIn, T* dataOut, size_t dataSize)
{
    for (int i = 0; i < dataSize; i++)
        dataOut[i] = dataIn[i];
}

template <typename T>
void PerformanceMeter<T>::copyIndirectionArr(T** dataIn, T** dataOut, size_t dataSize)
{
    for (int i = 0; i < dataSize; i++)
        *dataOut[i] = *dataIn[i];
}

结果:

-------------------测量int ---------------

数据:10 MB;迭代:1

顺序订单访问:8.50454ms

间接订单访问:11.6925ms

-------------------测量浮动------------

数据:10 MB;迭代:1

顺序订单访问:8.84023ms

间接订单访问:8.53148ms

-------------------测量双-----------

数据:10 MB;迭代:1

顺序订单访问:5.57747ms

间接订单访问:3.72843ms

1 个答案:

答案 0 :(得分:0)

以下是使用QMouseEvent *e; 从GCC 6.3获得的程序集输出的示例(使用T = int): copySequentialArrcopyIndirectionArr

从汇编中可以清楚地看出它们非常相似,但-O2需要两个copyIndirectionArr指令而不是mov。有了这个,我们可以得出结论,copySequentialArr是最快的。

使用copySequentialArrcopySequentialArrcopyIndirectionArr时也是如此。

<强>矢量

当我们开始使用T = doublecopySequentialArrcopyIndirectionArr时,这很有趣。 -O3没有变化,但copyIndirectionArr现在由编译器进行矢量化。在正常条件下,这种矢量化将使它比以前更快。

<强> Disclainmer

对于生成的汇编代码的这些检查是&#34;在上下文之外&#34;,在某种意义上,如果编译器知道上下文,它将进一步优化它。