Transactional Synchronization Extensions

来源:互联网 发布:淘宝创业项目 编辑:程序博客网 时间:2024/06/06 12:41

Transactional Synchronization Extensions

目录

  • 什么是TSX
  • 检测你的机器是否支持TSX
  • HLE
  • RTM
  • 参考资料

TSX

  TSX(Transactional Synchronization Extensions)是x86指令集体系结构的扩展,增加了对事务内存的支持,实现了硬件层面的无锁机制,可以加速多线程程序的执行。TSX为指定代码事务性执行提供了两个软解接口,分别是HLE(Hardware Lock Elision)和RTM(Restricated Transactional Memory)。HLE通过给特定指令加前缀实现的,能够向后兼容不支持TSX的处理器。RTM提供了新的指令,可以更加灵活的供程序员使用。[4]

检测你的机器是否支持TSX

  将下面的代码保存为has_tsx.c,编译后运行,即可得知你的机器是否支持TSX。

/* Filename:has_tsx.c */#include <cpuid.h>#include <stddef.h>#include <stdio.h>#define CPUID_RTM (1 << 11)#define CPUID_HLE (1 << 4)static inline int cpu_has_rtm(void){    if (__get_cpuid_max(0, NULL) >= 7) {        unsigned a, b, c, d;        __cpuid_count(7, 0, a, b, c, d);        return !!(b & CPUID_RTM);    }    return 0;}static inline int cpu_has_hle(void){    if (__get_cpuid_max(0, NULL) >= 7) {        unsigned a, b, c, d;        __cpuid_count(7, 0, a, b, c, d);        return !!(b & CPUID_HLE);    }    return 0;}int main(void) {    printf("RTM:%s", cpu_has_rtm()?"YES":"NO");    printf("HLE:%s", cpu_has_hle()?"YES":"NO");    return 0;}

HLE

什么是HLE

  HLE增加了两个指令前缀:XACQUIRE和XREALEASE。对于不支持TSX的处理器,这个前缀将会被忽略,所以说HLE向后兼容的。下面图片很清楚的解释了,如何使用上面提到的两个前缀,在软件层面使用HLE,实现对事务内存的支持。

http://www.anandtech.com/show/6290/making-sense-of-intel-haswell-transactional-synchronization-extensions/3

HLE的使用

#define __HLE_ACQUIRE ".byte 0xf2"#define __HLE_RELEASE ".byte 0xf3"#define __inline __attribute__((always_inline)) inline#define static __inline type                                 \        __hle_sub_fetch(type *ptr, type val)                 \        {                                                    \            type oldval = val;                               \            val = -val;                                      \            asm volatile(__HLE_ACQUIRE"; lock ; xadd %0, %1" \                        :"+q" (val), "+m"(*ptr)::"memory");  \            return val - oldval;                             \        }                                                    \#deifine static __inline void                                \        __hle_store(type *ptr, unsigned val)                 \        {                                                    \            asm volatile(__HLE_RELEASE"mov %1, %0"           \                        : "=m"(*ptr) : "q"(val) :            \                        "memory");                           \        }                                                    \

RTM

什么是RTM

  RTM(Restricted Transactional Memory)是事务内存的另外一种用法,它要比HLE更加灵活,因为当一次事务(transaction)失败时,我们可以给它指定一条回退路径,这要比HLE更加灵活些。
  RTM增加了三条新指令,分别是:XBEGIN,XEND和XABORT。XBEGIN和XEND标记了事务性代码的开始和结束,XABORT指令用来终止一个事务。如果事务失败,根据返回的状态值,指定一条备选路径;返回的状态值存放在eax中。

EAX register bit positionMeaning0Set if abort caused by XABORT instruction.1If set, the transaction may succeed on a retry. This bit is always clear if bit 0 is set.2Set if another logical processor conflicted with a memory address that was part of the transaction that aborted.3Set if an internal buffer overflowed.4Set if debug breakpoint was hit.5Set if an abort occurred during execution of a nested transaction.23:6reserved31:24XABORT argument (only valid if bit 0 set, otherwise reserved).

  TSX还有另外一条指令XTEST,用来检测处理器是否正在处理事务性代码。

RTM相关的函数

1、 —-unsigned int _xbegin()
2、 —-_xend()
3、 —-_xabort()
3、 —-_xtest()

RTM相关函数的使用方式

   可以通过引入头文件使用封装好的函数,也可以使用内联汇编实现
  1、引入头文件: #include <immintrin.h>
  2、使用内敛汇编

/**/static inline int _xbegin() {    int ret = 0;    asm volatile(".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory");    return ret;}static inline void _xend() {    asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");}static inline void _xabort() {    asm volatile(".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory")}/* 检测处理器是否正在处理事务性代码 */static inline void _xtest() {    unsigned int out;    asm volatile(".byte 0x0f,0x01,0xd6 ; setnz %0" : "=r" (out) :: "memory");    return out;}

使用实例

 #include <immintrin.h> if ((status = _xbegin ()) == _XBEGIN_STARTED) {     ... transaction code...     _xend (); } else {     ... non transactional fallback path... }

编译运行 gcc -rtm test.c (如果引入头文件immintrin.h,编译的时候需要加“-rtm”)[1]

参考资料

[1]. Restricted Transactional Memory
[2]. hardware lock elision
[3]. Using HLE and RTM with older compilers with tsx-tools
[4]. Transactional_Synchronization_Extensions
[5]. Intel手册
[6]. 代码参考自

0 0
原创粉丝点击