本文介绍了上标记一个int无符号的编译器优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于从未预计需要-ve值的整数,人们可以unsigned int类型或者int。
从编译器的角度或纯粹的CPU周期的角度来看是有在x86_64什么区别吗?

For an integer that is never expected to take -ve values, one could unsigned int or int.From a compiler perspective or purely cpu cycle perspective is there any difference on x86_64 ?

推荐答案

这要看情况。它可能会有两种方式,具体取决于您正在使用 INT ,以及对底层硬件的特性做什么。

It depends. It might go either way, depending on what you are doing with that int as well as on the properties of the underlying hardware.

unsigned int类型的青睐一个明显的例子是整数除法运算。在C / C ++整数除法是应该的向零舍入的,而在86轮接近负无穷大的机器整数除法。另外,对于整数除法(移动等),各种优化的替代品也普遍对轮负无穷大。所以,为了满足标准要求,编译器被迫调整用另外的机器指令的符号的整数除法的结果。在无符号整数除法就不会出现这个问题,这就是为什么通常的整数除法工作快得多无符号类型比有符号类型的情况。

An obvious example in unsigned ints favor would be the integer division operation. In C/C++ integer division is supposed to round towards zero, while machine integer division on x86 rounds towards negative infinity. Also, various "optimized" replacements for integer division (shifts, etc.) also generally round towards negative infinity. So, in order to satisfy standard requirements the compiler are forced to adjust the signed integer division results with additional machine instructions. In case of unsigned integer division this problem does not arise, which is why generally integer division works much faster for unsigned types than for signed types.

例如,考虑这个简单的前pression

For example, consider this simple expression

rand() / 2

由MSVC编译这个前pression产生的code通常如下所示

The code generated for this expression by MSVC complier will generally look as follows

call        rand
cdq
sub         eax,edx
sar         eax,1

请注意,而不是一个单一的移位指令(特区)我们在这里看到了一大堆的说明,即我们的特区是两个额外的指令pceded $ p $(干熄焦)。这些额外的说明,以迫使它产生的正确(但从C语言点),结果那里只是为了调整的划分。请注意,编译器不知道你的价值永远是正的,所以它总是产生这些指令,无条件地。他们将永远不会做任何有用的,因此浪费CPU周期。

Note that instead of a single shift instruction (sar) we are seeing a whole bunch of instructions here, i.e our sar is preceded by two extra instructions (cdq and sub). These extra instructions are there just to "adjust" the division in order to force it to generate the "correct" (from C language point of view) result. Note, that the compiler does not know that your value will always be positive, so it has to generate these instructions always, unconditionally. They will never do anything useful, thus wasting the CPU cycles.

不看一看在code为

(unsigned) rand() / 2

这就是

call        rand
shr         eax,1

在这种情况下,单班的伎俩,这样就为我们提供了一个的天文学的速度更快code(为师单独)。

In this case a single shift did the trick, thus providing us with an astronomically faster code (for the division alone).

在另一方面,如果你是混合整数算术和FPU浮点算术,有符号整数类型可能因为FPU指令集包含立即指令加载/存储符号整数,但对于无符号整数无指示工作得更快值。

On the other hand, when you are mixing integer arithmetics and FPU floating-point arithmetics, signed integer types might work faster since the FPU instruction set contains immediate instruction for loading/storing signed integer values, but has no instructions for unsigned integer values.

为了说明这一点我们可以使用下面的简单功能

To illustrate this one can use the following simple function

double zero() { return rand(); }

生成的code一般是非常简单的。

The generated code will generally be very simple

call        rand
mov         dword ptr [esp],eax
fild        dword ptr [esp]

但是,如果我们改变功能

But if we change our function to

double zero() { return (unsigned) rand(); }

生成code将变为

the generated code will change to

call        rand
test        eax,eax
mov         dword ptr [esp],eax
fild        dword ptr [esp]
jge         zero+17h
fadd        qword ptr [__real@41f0000000000000 (4020F8h)]

这code是明显较大,因为FPU指令集不无符号整型工作,因此额外的调整加载未签名的值(这是什么条件 FADD 一样)。

This code is noticeably larger because the FPU instruction set does not work with unsigned integer types, so the extra adjustments are necessary after loading an unsigned value (which is what that conditional fadd does).

有其他上下文和可用于证明它工作无论哪种方式的例子。所以,再次,要看情况。但是总体来说,这一切都不会在你的程序的性能大局无所谓。我一般preFER使用无符号类型重新present无符号的数量。在我的code整数类型,99%是无符号。但我这样做纯粹观念上的原因,没有任何的性能提升。

There are other contexts and examples that can be used to demonstrate that it works either way. So, again, it all depends. But generally, all this will not matter in the big picture of your program's performance. I generally prefer to use unsigned types to represent unsigned quantities. In my code 99% of integer types are unsigned. But I do it for purely conceptual reasons, not for any performance gains.

这篇关于上标记一个int无符号的编译器优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 07:49