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这样的事情可能会导致指令占用许多周期,甚至每个周期出现许多指令,这取决于您如何安排代码


所有这些只是为了强调一点:这种优化对于特定的编译器和芯片组来说是非常特殊的。所以你必须编译、测试和测量。

编译、反汇编、比较。。。这将取决于你的编译器。假设这样建议其中一个,但是当你用你关心的编译器和平台测试它时,另一个更快。那么,与你的测试相比,苏的建议值多少钱呢?;-)您希望每秒执行多少次该操作?还有什么其他的操作