对不同类型的 expression1 << expression2 进行位位移会影响性能吗?
Can a bit bitwise shift expression1 << expression2 with different types hurt performance?
我想知道使用像这样的不同类型是否会降低一些性能:
unsigned int nr0 = 8;
unsigned char nrBitsToShift = 2; //unsigned char, ok?
nr0 <<= nrBitsToShift;
而不是这个:
unsigned int nr0 = 8;
unsigned int nrBitsToShift = 2;
nr0 <<= nrBitsToShift;
理论上,这完全取决于您的 CPU 硬件。
一个典型的现代 CPU 将有一个 CPU 指令将一个值移动给定的位数。一个 CPU 寄存器加载要移位的值,第二个寄存器加载要移位的位数。接下来是执行移位的实际 CPU 指令。
典型的 32 位或 64 位 CPU 将具有单独的 CPU 大小为 32 位或 64 位的寄存器,但会有不同的指令使用寄存器的整个宽度,或者只是其中的一部分。只是每个寄存器的最低 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 带宽不足之前,很难执行足够多的指令来让自己保持忙碌。
如果您确实设法测量了性能上的一些差异,那么它只会适用于您执行基准测试的特定硬件,原因如上。
我想知道使用像这样的不同类型是否会降低一些性能:
unsigned int nr0 = 8;
unsigned char nrBitsToShift = 2; //unsigned char, ok?
nr0 <<= nrBitsToShift;
而不是这个:
unsigned int nr0 = 8;
unsigned int nrBitsToShift = 2;
nr0 <<= nrBitsToShift;
理论上,这完全取决于您的 CPU 硬件。
一个典型的现代 CPU 将有一个 CPU 指令将一个值移动给定的位数。一个 CPU 寄存器加载要移位的值,第二个寄存器加载要移位的位数。接下来是执行移位的实际 CPU 指令。
典型的 32 位或 64 位 CPU 将具有单独的 CPU 大小为 32 位或 64 位的寄存器,但会有不同的指令使用寄存器的整个宽度,或者只是其中的一部分。只是每个寄存器的最低 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 带宽不足之前,很难执行足够多的指令来让自己保持忙碌。
如果您确实设法测量了性能上的一些差异,那么它只会适用于您执行基准测试的特定硬件,原因如上。