我有几个相互关联的问题。基本上,在我实现的算法中,单词w被定义为四个字节,因此它可以包含在uint32_t中。
但是,在算法的操作过程中,我经常需要访问单词的各个部分。现在,我可以用两种方法:

uint32_t w = 0x11223344;
uint8_t a = (w & 0xff000000) >> 24;
uint8_t b = (w & 0x00ff0000) >> 16;
uint8_t b = (w & 0x0000ff00) >>  8;
uint8_t d = (w & 0x000000ff);

然而,我的一部分人认为这不是特别有效。我想一个更好的方法是像这样使用联合表示:
typedef union
{
    struct
    {
        uint8_t d;
        uint8_t c;
        uint8_t b;
        uint8_t a;
    };
    uint32_t n;
} word32;

使用这个方法,我可以分配word32 w = 0x11223344;然后我可以访问
我需要的零件(w.a=11在小端)。
但是,在这个阶段,我遇到了endianness问题,即在big-endian系统中,我的结构定义不正确,因此我需要在传入单词之前对其重新排序。
我可以毫不费力地做到这一点。我的问题是,那么,第一部分(各种位和移位)与使用联合的实现相比是否有效?这两者一般有什么区别吗?在现代的x86_64处理器上,我应该走哪条路?endianness只是一条红鲱鱼吗?
当然,我可以检查程序集的输出,但我对编译器的知识并不渊博。我本以为联合会更有效,因为它基本上会转换为内存偏移,如下所示:
mov eax, [r9+8]

编译器会意识到在上面的位移位情况下发生了什么吗?
如果重要的话,我使用的是C99,特别是我的编译器是clang(llvm)。
提前谢谢。

最佳答案

如果需要AES,为什么不使用现有的实现?这对于支持AES的现代英特尔处理器尤其有利。
由于存储到加载转发(STLF)失败,union技巧可以减慢速度。这可能会发生,取决于处理器型号,如果您将数据写入内存,并在不同的数据类型(例如32位与8位)后立即将其读回。

关于c - C99中数据结构的效率(可能受字节顺序影响),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4531418/

10-12 05:18