簡體   English   中英

如何計算c++中冒泡排序、插入排序和選擇排序功能的時間(以毫秒為單位)

[英]How to calculate time in milliseconds of functions of bubble sort, insertion sort and selection sort in c++

應該使用哪些函數來計算 function 的時間是否有任何內置 function 用於此目的。

您可以使用以下代碼:

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;

沒有專門用於計算 function 所用時間的內置內容。

有內置的函數來檢索當前時間。 有關詳細信息,請參閱std::chrono::high_resolution_clock::now()

要對 function 計時,您將(至少通常)在進入 function 之后檢索當前時間,並在退出之前再次檢索。

然后,您可以將兩者相減,並使用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;
}

這使您可以傳遞一些任意的 function(以及 arguments 傳遞給該函數)並打印出 function 執行的時間。 目前它正在執行微秒,但將其更改為毫秒應該是微不足道的。

最后,這將返回名為 function 產生的任何值,所以如果你有類似的東西:

x = f(a, b, c);

您可以將其替換為:

x = timer(f, a, b, c);

...打印出f所消耗的時間。

我通常不以秒為單位計算時間,因為它在具有不同 CPU 頻率的機器上會有所不同。 我通常使用 CPU 周期,這樣如果您在筆記本電腦或超頻的高端服務器上運行,它將大致相同。 周期還可以更好地反映和關聯其他機器特性,如 CPU 緩存延遲。 這是 Linux kernel 內部使用的

# 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 start = now();
call_my_algo();
uint64_t t1 = now();
uint64_t ticks = t1>=t0 ? t1-t0 : (std::numeric_limits<uint64_t>::max() - t0)+t1;

有幾件事需要注意。 每個核心都包含自己的時間戳計數器,因此如果它們不同步,那么如果進程從一個核心移動到另一個核心,或者新的時間戳可能低於 start 從而差異變為負數,那么您可能會讀取錯誤 - 因此滴答聲將下溢. 但是這些現在很少見,在舊機器中更常見。

您可以檢查您機器上的 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 start = 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();
}

還有 memory 屏障的問題可能非常涉及。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM