我m writing simple benchmark on C++ to compare the execution time of data access on different platforms.And I
得到奇怪的结果。我测量顺序顺序访问和间接顺序访问的时间。为此,我只是以两种不同的方式将一个数组数据复制到另一个数组数据。代码和结果如下。 我得到的时间是模棱两可的。对 int 数据类型的评估表明,顺序访问更快(没问题)。但对于浮点型和双精度型,情况正好相反(请参阅下面的时间结果)。也许我做错了基准测试,或者有一些我没有考虑到的陷阱?或者,您能否建议一些基准工具来比较不同数据类型的数据访问或简单操作性能?
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];
}
结果:
-------------------测量---------------
数据: 10 MB ; 迭代次数: 1
顺序顺序访问:8.50454ms
间接顺序访问:11.6925ms
-------------------测量浮点数------------
数据: 10 MB ; 迭代次数: 1
顺序顺序访问:8.84023ms
间接顺序访问:8.53148ms
-------------------测量双倍-----------
数据: 10 MB ; 迭代次数: 1
顺序顺序访问:5.57747ms
间接顺序访问:3.72843ms
以下是使用-O2
的 GCC 6.3 程序集输出的示例(使用T = int
):copySequentialArr
和copyIndirectionArr
.
从程序集中可以清楚地看出它们非常相似,但是copyIndirectionArr
需要两个mov
指令,而不是copySequentialArr
。有了这个,我们可以在某种程度上得出结论,copySequentialArr
是最快的。
使用T = double
时也是如此:copySequentialArr
和copyIndirectionArr
。
矢 量化
当我们开始使用时会变得很有趣-O3
:copySequentialArr
和copyIndirectionArr
.copyIndirectionArr
没有变化,但copySequentialArr
现在由编译器矢量化。在正常情况下,这种矢量化将使其比以前更快。
声明者
对生成的汇编代码的这些检查是"脱离上下文的",从某种意义上说,如果编译器了解上下文,它将进一步优化它。