[英]pybind11 c++ unordered_map 10x slower than python dict?
[英]Why the execution time of same function definition within a class is slower more than 10x time?
不確定compiler
執行哪種優化,但為什么在類中相同的函數定義比調用全局方法的速度慢?
#include <iostream>
#include <chrono>
#define MAX_BUFFER 256
const int whileLoops = 1024 * 1024 * 10;
void TracedFunction(int blockSize) {
std::chrono::high_resolution_clock::time_point pStart;
std::chrono::high_resolution_clock::time_point pEnd;
double A[MAX_BUFFER];
double B[MAX_BUFFER];
double C[MAX_BUFFER];
// fill A/B
for (int sampleIndex = 0; sampleIndex < MAX_BUFFER; sampleIndex++) {
A[sampleIndex] = sampleIndex;
B[sampleIndex] = sampleIndex + 1000.0;
}
// same traced function
pStart = std::chrono::high_resolution_clock::now();
int whileCounter = 0;
while (whileCounter < whileLoops) {
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
double value = A[sampleIndex] + B[sampleIndex];
C[sampleIndex] = value;
}
whileCounter++;
}
pEnd = std::chrono::high_resolution_clock::now();
std::cout << "execution time: " << std::chrono::duration_cast<std::chrono::milliseconds>(pEnd - pStart).count() << " ms" << " | fake result: " << A[19] << " " << B[90] << " " << C[129] << std::endl;
}
class OptimizeProcess
{
public:
std::chrono::high_resolution_clock::time_point pStart;
std::chrono::high_resolution_clock::time_point pEnd;
double A[MAX_BUFFER];
double B[MAX_BUFFER];
double C[MAX_BUFFER];
OptimizeProcess() {
// fill A/B
for (int sampleIndex = 0; sampleIndex < MAX_BUFFER; sampleIndex++) {
A[sampleIndex] = sampleIndex;
B[sampleIndex] = sampleIndex + 1000.0;
}
}
void TracedFunction(int blockSize) {
// same traced function
pStart = std::chrono::high_resolution_clock::now();
int whileCounter = 0;
while (whileCounter < whileLoops) {
for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
double value = A[sampleIndex] + B[sampleIndex];
C[sampleIndex] = value;
}
whileCounter++;
}
pEnd = std::chrono::high_resolution_clock::now();
std::cout << "execution time: " << std::chrono::duration_cast<std::chrono::milliseconds>(pEnd - pStart).count() << " ms" << " | fake result: " << A[19] << " " << B[90] << " " << C[129] << std::endl;
}
};
int main() {
int blockSize = MAX_BUFFER;
// outside class
TracedFunction(blockSize);
// within class
OptimizeProcess p1;
p1.TracedFunction(blockSize);
std::cout << std::endl;
system("pause");
return 0;
}
試過MSVC
, /Oi /Ot
。
~80ms vs 1200ms。 是否在compile-time
使用blockSize
作為常量進行循環展開?
不確定,因為我試圖將blockSize
隨機設置為:
std::mt19937_64 gen{ std::random_device()() };
std::uniform_real_distribution<double> dis{ 0.0, 1.0 };
int blockSize = dis(gen) * 255 + 1;
結果相同......
如果使用GCC的最大優化標志(即O3
進行編譯,那么您將獲得類似的執行時間。
在執行時間內執行函數或不執行函數的方面沒有區別。
我看到的唯一區別是,您何時以及如何創建陣列。 在第一個函數中,數組是函數的自動變量。 在within函數中,數組是類的數據成員。
在某些情況下,這可以發揮作用。 使數組全局化(僅創建一次),您將看到執行時間沒有差異(無論使用O1
, O2
還是O3
)。
注意:使用O2
編譯,您將獲得內部函數更快的執行時間(這與您提到的相反)。 准確地說是x1.35加速,正如您在Live Demo中看到的那樣。
不過,請記住,當優化正確完成時,在這種情況下使用O3
,您不應該看到任何重大差異!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.