C++ 这两种将数组转换为整数的方法中,您建议使用哪一种?
考虑以下要转换为单个无符号整数的字节数组:C++ 这两种将数组转换为整数的方法中,您建议使用哪一种?,c++,arrays,performance,integer,C++,Arrays,Performance,Integer,考虑以下要转换为单个无符号整数的字节数组: unsigned char arr[3] = {0x23, 0x45, 0x67}; 每个字节表示整数中的等效字节,现在您建议使用以下哪种方法来提高性能: unsigned int val1 = arr[2] << 16 | arr[1] << 8 | arr[0]; //or unsigned int val2=arr[0]; *((char *)&val2+1)=arr[1]; *((char *)&val
unsigned char arr[3] = {0x23, 0x45, 0x67};
每个字节表示整数中的等效字节,现在您建议使用以下哪种方法来提高性能:
unsigned int val1 = arr[2] << 16 | arr[1] << 8 | arr[0];
//or
unsigned int val2=arr[0];
*((char *)&val2+1)=arr[1];
*((char *)&val2+2)=arr[2];
unsigned int val1=arr[2]我相信比特移位将是最快的解决方案。在我看来,CPU可以直接滑入值中,但通过直接转到地址(如第二个示例),它将必须使用许多临时存储器。我相信bitshift将是最快的解决方案。在我看来,CPU可以直接滑入值中,但通过直接转到地址(如第二个示例),它将必须使用许多临时存储器。我更喜欢第一种方法,因为它是可移植的。第二种方法不是因为问题。我更喜欢第一种方法,因为它是可移植的。第二个不是因为问题。第一个更快,翻译成x86 asm。这取决于你的架构。通常,编译器能够很好地优化第一个表达式,而且它的可移植性也更高第一个更快,用x86 asm翻译。这取决于你的架构。通常编译器能够很好地优化第一个表达式,而且它的可移植性也更高性能取决于编译器和机器。例如,在我在x64上使用GCC4.4.5进行的实验中,第二个稍微快一点,而其他人则报告第一个更快。因此,我建议坚持使用第一种方法,因为它更干净(无强制转换)和更安全(无端点问题)。性能取决于编译器和机器。例如,在我在x64上使用GCC4.4.5进行的实验中,第二个稍微快一点,而其他人则报告第一个更快。因此,我建议坚持使用第一种方法,因为它更干净(无强制转换)和更安全(无端点问题)。我建议使用union解决方案:
union color {
// first representation (member of union)
struct s_color {
unsigned char a, b, g, r;
} uc_color;
// second representation (member of union)
unsigned int int_color;
};
int main()
{
color a;
a.int_color = 0x23567899;
a.uc_color.a;
a.uc_color.b;
a.uc_color.g;
a.uc_color.r;
}
注意it平台依赖性(即endianess)我建议使用union解决方案:
union color {
// first representation (member of union)
struct s_color {
unsigned char a, b, g, r;
} uc_color;
// second representation (member of union)
unsigned int int_color;
};
int main()
{
color a;
a.int_color = 0x23567899;
a.uc_color.a;
a.uc_color.b;
a.uc_color.g;
a.uc_color.r;
}
注意it平台依赖性(哪种端性)这很大程度上取决于您的特定处理器
例如,在PowerPC上,第二种形式——通过字符指针写入——遇到了一个称为加载命中存储的复杂实现细节。这是一个CPU暂停,当您存储到内存中的某个位置,然后在存储完成之前再次将其读回时发生。在存储完成之前,加载操作无法完成(大多数PPC没有内存存储转发),存储可能需要许多周期才能从CPU输出到内存缓存
由于存储和算术单元在管道中的排列方式,CPU将必须完全刷新管道,直到存储完成:这可能是CPU停止死机的20个或更多周期的暂停。一般来说,在这个平台上,写入内存然后立即读回是非常糟糕的。因此,在这种情况下,顺序位移位会快得多,因为它们都发生在寄存器上,并且不会引起管道暂停
在奔腾系列上,情况可能完全相反,因为该芯片组具有存储转发和快速堆栈架构,并且架构寄存器相对较少。在核心Duos和I7上,它可能再次反转,因为它们的管道非常深
记住:并非每个操作码都需要一个周期。CPU并不简单,类似and这样的事情可能会导致指令占用许多周期,甚至每个周期出现许多指令,这取决于您如何安排代码
所有这些只是为了强调一点:这种优化对于特定的编译器和芯片组来说是非常特殊的。因此,您必须编译、测试和测量。这在很大程度上取决于您的特定处理器
例如,在PowerPC上,第二种形式——通过字符指针写入——遇到了一个称为加载命中存储的复杂实现细节。这是一个CPU暂停,当您存储到内存中的某个位置,然后在存储完成之前再次将其读回时发生。在存储完成之前,加载操作无法完成(大多数PPC没有内存存储转发),存储可能需要许多周期才能从CPU输出到内存缓存
由于存储和算术单元在管道中的排列方式,CPU将必须完全刷新管道,直到存储完成:这可能是CPU停止死机的20个或更多周期的暂停。一般来说,在这个平台上,写入内存然后立即读回是非常糟糕的。因此,在这种情况下,顺序位移位会快得多,因为它们都发生在寄存器上,并且不会引起管道暂停
在奔腾系列上,情况可能完全相反,因为该芯片组具有存储转发和快速堆栈架构,并且架构寄存器相对较少。在核心Duos和I7上,它可能再次反转,因为它们的管道非常深
记住:并非每个操作码都需要一个周期。CPU并不简单,类似and这样的事情可能会导致指令占用许多周期,甚至每个周期出现许多指令,这取决于您如何安排代码
所有这些只是为了强调一点:这种优化对于特定的编译器和芯片组来说是非常特殊的。所以你必须编译、测试和测量。编译、反汇编、比较。。。这将取决于你的编译器。假设这样建议其中一个,但是当你用你关心的编译器和平台测试它时,另一个更快。那么,与你的测试相比,苏的建议值多少钱呢?;-)您希望每秒执行多少次该操作?还有什么其他的操作