x86架构特点整理

字节序

任何学过计算机网络的人都应该知道,x86是反的(分不清啥是大端啥是小端)。

PowerPC(老的mac本,任天堂的WII)是正的。

ARM是可以切换的。

 

内存对齐访问

不管什么架构,肯定支持在任意地址访问byte。

但是要访问int16_t、int32_t和int64_t,很多架构要求被访问的地址要按照sizeof(T)对齐,否则,在linux下你会收到一个SIGBUS。

不过x86就无所谓了,不用对齐也能访问。

 

SIMD寄存器

常见的配置是128bit的,也有256bit的,某些至强的架构还有512bit的。

也就是说你一次就可以load或者store这么宽的数据。

比如我们可以用SSE指令集来利用SIMD实现strcpy之类的函数的优化,这种优化一般叫向量化操作。

 

CMPXCHG16B

就是支持CAS操作的指令,最早的CMPXCHG是int32_t宽的,后来的CMPXCHG8B是int64_t宽的,现在的CMPXCHG16B则是128bit宽的。

使用gcc的话,直接用gcc内置的类型__int128_t来调用__sync_bool_compare_and_swap或者__sync_val_compare_and_swap即可使用CMPXCHG16B,同时加上命令行参数-mcx16来启用。

在实践中发现,调用CMPXCHG16B的时候,是要求目的地按照128bit宽对齐的,否则会收到SIGSEGV。

例如你想对成员变量m_array进行此操作,可以用gcc的标记来保证这个对齐:

class A {
private:
    int16_t m_steppingStone;  // 导致后面的m_array无法按照128bit对齐
    int64_t m_array  __attribute__ ((aligned (16)));
public:
    // ...
};

 或者使用union,编译器看到__int128_t就会对齐这个union的:

class A {
private:
    int16_t m_steppingStone;  // 导致后面的m_array无法按照128bit对齐
    union {
        __int128_t i128;
        int64_t a[2];
    } m_array;
public:
    // ...
};

 当然你如果直接用__int128_t肯定就更会对齐了,只不过你在写CAS(128bit)的时候,一般是利用128bit的宽度来处理多个更小相邻宽度之间的同步的逻辑,用__int128_t你就得在调用的时候自己多转换一下了。

你可能感兴趣的:(架构)