我想測量我撰寫的函式在執行時所花費的時間。雖然關于如何在 C 中測量時間的 SO 上有很多執行緒,但我沒有找到任何解釋如何防止編譯器優化以清除我的函式呼叫的執行緒。所以現在我做這樣的事情:
bool testFunctionSpeed() {
auto input = loadInput();
auto start = std::chrono::high_resolution_clock::now();
for (int i; i < num_iterations; i ) {
auto result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
}
它現在似乎可以作業,但我不確定這是否穩定,因為:這樣做,編譯器可以看到存盤在“result”中的結果沒有在回圈范圍之外使用,因此它可能只是優化代碼消失(...對吧?)。
我知道有一些標志不能優化代碼,但是我想在“真實”條件下對我的代碼進行基準測驗!一種方法是隨機列印出部分結果,但這似乎不是一個“正確”的解決方案。
什么是正確的方法?
uj5u.com熱心網友回復:
為了防止編譯器優化掉函式呼叫,只需將該函式的輸入和輸出volatile設為變數即可。
保證在每次回圈運行時計算結果并將其存盤在易失性輸出變數中。
雖然 volatile輸入會阻止優化器預先計算函式的值,但如果您不將輸入標記為 volatile 則編譯器可能只會在每次回圈迭代時寫入一個常量來輸出結果變數。
單擊Try it online!下面的鏈接查看正在運行的程式和程式集串列。
您的改進代碼示例如下:
在線試試吧!
#include <cmath>
#include <iostream>
#include <chrono>
int function(int x) {
return int(std::log2(x));
}
bool testFunctionSpeed() {
size_t const num_iterations = 1 << 20;
auto volatile input = 123;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < num_iterations; i) {
auto volatile result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
end - start).count() / num_iterations;
std::cout << duration << " ns per iteration" << std::endl;
return true;
}
int main() {
testFunctionSpeed();
}
輸出:
8 ns per iteration
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389806.html
