[英]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.