應該使用哪些函式來計算函式的時間 是否有任何內置函式用于此目的。
uj5u.com熱心網友回復:
您可以使用此代碼:
auto a = chrono::steady_clock::now();
//write your code here
auto b = chrono::steady_clock::now();
double time = chrono::duration <double, milli> (b - a).count();
cout << endl << "Time ---> " << time;
uj5u.com熱心網友回復:
沒有專門用于計算函式所用時間的內置內容。
有內置的函式來檢索當前時間。有關std::chrono::high_resolution_clock::now()更多詳細資訊,請參閱。
要為函式計時,您(至少通常情況下)會在進入函式后立即檢索當前時間,并在退出之前再次檢索當前時間。
然后,您可以將兩者相減,并使用方便std::duration_cast的周期(毫秒、微秒或納秒,視情況而定)將其轉換為持續時間。
把它們放在一起,你可以(例如)得到這樣的東西:
template <class T, class U, template<class, class> class F, typename ...Args>
auto timer(F<T,U> f, std::string const &label, Args && ...args) {
using namespace std::chrono;
auto start = high_resolution_clock::now();
auto holder = f(std::forward<Args>(args)...);
auto stop = high_resolution_clock::now();
std::cout << label << " time: " << duration_cast<microseconds>(stop - start).count() << "\n";
return holder;
}
這使您可以傳遞一些任意函式(以及要傳遞給該函式的引數)并列印出執行該函式所花費的時間。目前它正在執行微秒,但將其更改為毫秒應該是微不足道的。
最后,這將回傳被呼叫函式產生的任何值,所以如果你有類似的東西:
x = f(a, b, c);
您可以將其替換為:
x = timer(f, a, b, c);
...獲取f列印出來所消耗的時間。
uj5u.com熱心網友回復:
我通常不以秒為單位計算時間,因為在具有不同 CPU 頻率的機器上它會有所不同。我通常使用 CPU 周期,因此如果您在筆記本電腦或超頻的高端服務器上運行,它的數量大致相同。周期還可以更好地反映 CPU 快取延遲等其他機器特性并與之相關聯。這是Linux內核內部使用的
# cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc
每個 CPU 架構都有某種內部時間戳計數器。在 x86_64 上,TSC(時間戳計數器)可以用 Intel 內在的 '__builtin_ia32_rdtsc()` 讀取,如
#include <cstdint>
static inline std::uint64_t now() {
return __builtin_ia32_rdtsc();
}
然后在您的代碼上,您可以執行以下操作:
std::uint64_t t0 = now();
call_my_algo();
uint64_t t1 = now();
uint64_t ticks = t1>=t0 ? t1-t0 : (std::numeric_limits<uint64_t>::max() - t0) t1;
最后一行是處理翻轉,但這應該每 177 年發生一次,所以不是真正的問題。你可以逃脫t1-t0。
rdtsc 呼叫 std::chrono 的優勢在于您不會呼叫 glibc 和內核,這正是 chrono 最終所做的。開銷很小,因此這種方法非常適合微基準測驗。
有幾件事需要注意。每個內核都包含自己的時間戳計數器,因此如果它們不同步,那么如果行程從一個內核移動到另一個內核,您可能會得到錯誤的讀數,或者新的時間戳可能低于開始時間,從而使差異變為負數 - 因此滴答將下溢. 但這些現在很少見,在舊機器中更常見。
您可以檢查您機器上的 TSC 是否值得信任
cat /proc/cpuinfo | grep tsc | tr ' ' '\n' | grep tsc | sort | uniq
constant_tsc
nonstop_tsc
rdtscp
tsc
tsc_scale
constant_tsc - 時間戳計數器頻率恒定
nonstop_tsc - 計數器不會在 C 狀態下停止
rdtscp - cpu 有 rdtscp 指令(回傳時間戳和核心)
tsc - cpu 有時間戳計數器
tsc_scale - amd tsc 縮放支持
你應該小心,無論你是否使用 std::chrono,它最終會在 Linux 上呼叫 clock_gettime(),或者如果你使用 TSC,編譯器可能會反轉你的陳述句的順序,這樣上面的代碼就可以變成
std::uint64_t t0 = now();
uint64_t t1 = now();
uint64_t ticks = t1>=t0?t1-t0 : (std::numeric_limits<uint64_t>::max() - t0) t1;
call_my_algo();
因此,您將不會測量任何東西。避免這種情況的一種方法是放置優化障礙,例如
#include <cstdint>
static inline std::uint64_t now() {
asm volatile ( "" ::: "memory" );
return __builtin_ia32_rdtsc();
}
還有可能非常涉及的記憶體障礙問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/373617.html
