C++ 将unsigned int更改为size\t会影响性能吗?

C++ 将unsigned int更改为size\t会影响性能吗?,c++,performance,C++,Performance,在我将一些遗留代码从win32移植到win32 64之后,在我讨论了消除“可能丢失数据”警告()的最佳策略之后。我将用代码中的size\u t替换许多unsigned int 然而,就性能而言,我的代码是至关重要的(我甚至不能在调试中运行它……太慢了) 我做了一个快速的基准测试: #include "stdafx.h" #include <iostream> #include <chrono> #include <string> template<t

在我将一些遗留代码从win32移植到win32 64之后,在我讨论了消除“可能丢失数据”警告()的最佳策略之后。我将用代码中的
size\u 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;
}
为x86编译,它输出:

Elapsed 2185ms
Elapsed 2157ms
Elapsed 2756ms
Elapsed 2748ms
因此,显然使用
size\u t
而不是
unsigned int
对性能影响不大。但事实总是如此(很难以这种方式衡量绩效)

unsigned int
更改为
size\u t
是否会影响CPU性能(现在将处理64位对象而不是32位对象)?

肯定不会。在现代(甚至更老的)CPU上,64位整数运算的速度与32位运算的速度一样快。

i7 4600u上算术运算的示例
a*b/c

(int32\u t)*(int32\u t)/(int32\u t)
:1.3 nsec
(int64\u t)*(int64\u t)/(int64\u t)
:1.3 nsec

为x64目标编译的两个测试(与您的目标相同)。


然而,如果您的代码管理充满整数的大对象(例如,大整数数组),使用
size\u t
而不是
unsigned int
可能会影响性能,如果缓存未命中计数增加(较大的数据可能会超过缓存容量)。检查对性能影响的最可靠方法是在这两种情况下测试应用程序。使用您自己的类型typedef'ed进行
size\t
unsigned int
然后对您的应用程序进行基准测试。

查看生成的汇编代码并尝试测量性能。您进行基准测试了吗?结果如何?你怎么查的?如果没有代码显示,答案是“是的,它可能会影响性能”。但不清楚是朝哪个方向走。@CoryKramer:OP说他使用的是Win64,它使用64位
size\u t
和IL32。因此结论是正确的。
size\u t
表示对象的大小。你不应该真的把它用在其他意义上。另外,
int_fast32_t
uint_fast32_t
是typedef,它将解析为一些int大小,至少32位,这对于平台来说是最快的。你不应该为了避免虚假的警告而破坏你的代码。如果警告是真实的,并且确实需要更大的类型才能使代码正常工作,那么必须使用更大的类型。如果警告是虚假的,那么除了更改类型之外,还可以通过其他方式忽略、禁用或隐藏它们。@M.M如果警告是虚假的,那么可以通过其他方式忽略、禁用或隐藏它们。如果以后的更改引入了需要您禁用的警告的代码,则会出现这样做的问题。在我看来,最好根据所使用的函数/方法使用较大的大小,而不要忽略或禁用警告,因为“知道”代码是正确的。如果编写您用来将代码转换为可运行二进制代码的编译器的人员花费额外时间发出警告,因为他们认为您所做的是不可靠的,您最好听他们说。64位操作会略微增加x86-64上的代码大小,因为更多指令需要REX前缀。这通常并不重要。Silvermont对于
imul r64,r64
的延迟和吞吐量略差于
imul r32,r32
,而Atom对于64位乘法的性能差得多。对于shift、add/sub和boolean等简单操作,指令计时没有区别。(见附件)。你是对的,在“普通”CPU上,64位整数运算是全速的。你绝对正确,主要的速度问题是缓存占用。值得一看常用的数据结构,看看它们是否仍然适用于
uint32\u t
。不过,不要担心在
size\u t
uint32\u t
之间进行转换:在x86-64上写入寄存器的32位低位时,64位的零扩展是免费的。因此,使用
size\t
temporaries很好,除非代码依赖于无符号换位运算……在英特尔CPU(包括Haswell)上,实际64位除以非编译时常量的值要比32位整数慢得多。和。只有当除数为常数时(这是非常正常的情况),测试结果才可能用于吞吐量。(有符号64位idiv也比无符号div慢)