[英]May changing unsigned int to size_t impact performances?
在我將一些遺留代碼從 win32 移植到 win64 之后,在我討論了消除警告“可能丟失數據” 的最佳策略是什么之后(擺脫“警告 C4267 可能丟失數據”的最佳策略是什么? )。 我將在我的代碼中用size_t
替換許多unsigned int
。
但是,我的代碼在性能方面至關重要(我什至無法在調試中運行它......太慢了)。
我做了一個快速的基准測試:
#include "stdafx.h"
#include <iostream>
#include <chrono>
#include <string>
template<typename T> void testSpeed()
{
auto start = std::chrono::steady_clock::now();
T big = 0;
for ( T i = 0; i != 100000000; ++i )
big *= std::rand();
std::cout << "Elapsed " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count() << "ms" << std::endl;
}
int main()
{
testSpeed<size_t>();
testSpeed<unsigned int>();
std::string str;
std::getline( std::cin, str ); // pause
return 0;
}
為 x64 編譯,它輸出:
Elapsed 2185ms
Elapsed 2157ms
為 x86 編譯,它輸出:
Elapsed 2756ms
Elapsed 2748ms
所以顯然使用size_t
而不是unsigned int
對性能影響不大。 但是真的總是這樣嗎(很難以這種方式對性能進行基准測試)。
是否/可能將unsigned int
更改為size_t
影響 CPU 性能(現在將操作 64 位對象而不是 32 位)?
當然不。 在現代(甚至更老)CPU上,64位整數運算的執行速度與32位運算一樣快。
我的i7 4600u上用於算術運算a * b / c
示例:
(int32_t) * (int32_t) / (int32_t)
:1.3 ns
(int64_t) * (int64_t) / (int64_t)
:1.3 ns
兩種測試均針對x64目標(與您的目標相同)進行編譯。
但是,如果您的代碼管理的是裝滿整數的大對象(大整數數組,例如fox),則如果緩存未命中計數增加(更大的數據可能會超過緩存容量),則使用size_t
而不是unsigned int
可能會對性能產生影響。 檢查性能影響的最可靠方法是在兩種情況下都測試您的應用程序。 使用您自己的typedef'ed到size_t
或unsigned int
然后對應用程序進行基准測試。
至少在Intel上,如果沒有數據依賴性,則ALU可以並行執行兩個32位操作。 如果size_t
為64位,則只能執行一項操作。
在你的榜樣,是沒有區別的,因為你有一個數據DEP( big
取決於自身。)
但是,您可能會在代碼中看到差異,例如:
uint32_t a = std::rand();
uint32_t b = std::rand();
const uint32_t randVal = std::rand();
for (int i = 0; i < 10000000; ++i) {
a += randVal;
b += randVal;
}
如果將a
和b
切換到uint64_t
,則該循環的運行速度可能會變慢,因為一次只能執行一次操作。
注意,ALU不能與16位整數並行執行4個運算,也不能與8位整數並行執行8個運算。 對於32位數據,只有2個操作,對於64位數據,只有1個操作。
注意:這在生成的機器代碼中看不到。 這種並行化發生在CPU中。
編輯:另外,看這部分由安德烈Alexandrescu的談話,他提到了這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.