簡體   English   中英

如何測量for循環的速度差異?

[英]How can I measure the speed difference of for loop?

我很好奇 for 循環中的以下項目。

  1. for(auto) 與 for(auto &)

  2. 分離for循環

  3. for(auto &) 與 for(const auto &)

  4. for(int: list) vs for(auto: list) [列表是 integer 向量]

因此,我編寫了以下代碼用於在 C++17 版本中進行測試。

CMake 調試模式似乎有所不同(未優化)

// In debug mode
1. elapsed: 7639 (1663305922550 - 1663305914911)
2. elapsed: 3841 (1663305926391 - 1663305922550)
3. elapsed: 3810 (1663305930201 - 1663305926391)

但是在release模式下(用gcc -O3)1~3沒有區別

// release mode
1. elapsed: 0 (1663305408984 - 1663305408984)
2. elapsed: 0 (1663305409984 - 1663305409984)
3. elapsed: 0 (1663305410984 - 1663305410984)

不知道是我的測試方法不對,還是根據優化狀態沒有區別是正確的?

這是我的測試源代碼。

// create test vector
const uint64_t max_ = 499999999;    // 499,999,999
std::vector<int>   v;
for (int i = 1; i < max_; i++)
    v.push_back(i);


// test 1.
auto start1 = getTick();
for (auto& e : v)
{
    auto t = e + 100;    t += 300;
}
for (auto& e : v)
{
    auto t = e + 200;    t += 300;
}
auto end1 = getTick();


// test 2.
// Omit tick function
for (auto& e : v)
{
    auto t1 = e + 100;    t1 += 300;
    auto t2 = e + 200;    t2 += 300;
}


// test 3.
for (auto e : v)
{
    auto t1 = e + 100;    t1 += 300;
    auto t2 = e + 200;    t2 += 300;
}

...

然后,通過chrono毫秒獲得getTick()。

uint64_t getTick()
{
    return (duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
}

此外,此測試在 Debian aarch64 上進行

  • Jetson Xavier NX(噴氣背包 4.6,ubuntu 18.04LTS)
  • 8Gb 內存
  • GCC 7.5.0

如有不妥請指教。 謝謝!

一個空循環可以優化掉,所以你的編譯器可以正確地做到這一點。 但是禁用優化的基准測試沒有意義 C++ 需要優化以獲得我們期望的生產使用性能(尤其是使用模板庫函數),並且優化與否並不是一個常數因子加速; 它使表達相同邏輯的不同方式導致不同的asm,在通常優化的構建中,它們會編譯為相同的asm。

您無法從調試版本中推斷出發布版本中更快的內容,而不是像這樣的小規模微優化。 另請參閱績效評估的慣用方式?

啟用優化后,如果您只使用該副本的一個成員,則復制到本地 object 可以刪除大部分工作。 習慣於思考代碼實際需要進行的實際工作; 編譯器通常會找出最小值是多少。 例如, auto &實際上並不會將指針放入寄存器並取消引用它超出它首先循環數組所做的操作,引用變量實際上並不作為單獨的存在於 asm 中的任何位置寄存器或 memory 中的值。

因此,如果沒有循環中的一些實際工作(例如對數組求和或修改每個元素),這不是您可以在基准測試中隔離的東西。 您可以嘗試使用Benchmark::DoNotOptimize或類似的內聯 asm 來使編譯器在不執行任何其他操作的情況下實現寄存器中的值,但要確保您的基准測試完全正確,您需要了解 asm 並檢查編譯器 output。 (微基准測試很難。)在這種情況下,您可能已經可以通過查看 asm 來回答這個問題,並且在正常情況下它是相同的。

在啟用優化的情況下檢查哪些東西都編譯到相同的 asm 可能更容易,而不是試圖猜測實驗時間的微小差異是由於噪聲還是可能是真正的差異。 (如果有區別,是否只是巧合,在這個特定的 CPU 上,代碼 alignment 和周圍代碼的抽簽速度更快。)

-O3模式將進行編譯優化並刪除代碼。 您可以嘗試在 for-loop 全局中聲明變量以避免編譯器優化。

暫無
暫無

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

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