我想知道你是否可以通过使用这样的不同类型来失去一些性能:
unsigned int nr0 = 8;
unsigned char nrBitsToShift = 2; //unsigned char, ok?
nr0 <<= nrBitsToShift;
而不是:
unsigned int nr0 = 8;
unsigned int nrBitsToShift = 2;
nr0 <<= nrBitsToShift;
答案 0 :(得分:2)
理论上,这一切都取决于你的CPU硬件。
典型的现代CPU将有一条CPU指令,用于将值移位给定的位数。一个CPU寄存器加载一个要移位的值,第二个寄存器加载了要移位的位数。接下来是执行转换的实际CPU指令。
典型的32位或64位CPU将具有32或64位大小的单独CPU寄存器,但将使用不同的指令,这些指令使用寄存器的整个宽度,或仅使用其一部分。只是每个寄存器的最低8位,16位或32位,可能有一个选项,用于将最低的8/16/32位值解释为有符号值或无符号值,这一点很重要。
鉴于此背景信息,让我们重新审视相关代码:
unsigned int nr0 = 8;
unsigned char nrBitsToShift = 2; //unsigned char, ok?
nr0 <<= nrBitsToShift;
不言而喻,我们将忽略现代编译器在此处执行的明显优化。现代编译器可能会在编译时评估此代码序列。但是,让我们忽略这一点,让我们说这是从字面上翻译成机器代码。
在这种情况下,如果所讨论的CPU具有左移CPU指令,该指令指定在寄存器的最低8位中移位的位数,则左移位操作直接转换为机器代码。但是,唯一的左移CPU指令可能使用CPU寄存器的全部16位,32位或64位,以便移位的位数。在这种情况下,必须执行额外的CPU指令以将8位值扩展为16位,32位或64位。
这当然是一个主要是理论上的讨论。要获得实际答案,请尝试编译一些测试代码,禁用所有编译器优化,并对其进行基准测试。我实际上怀疑会观察到性能的显着差异。对于现代硬件,瓶颈通常是RAM或I / O带宽。现代CPU在缺乏I / O带宽之前,无法执行足够的指令以保持忙碌。
如果您确实设法衡量某些性能差异,那么它仅适用于您执行基准测试的特定硬件,原因如上所述。