__asm__("pause")用法

11 篇文章 0 订阅
static inline int 		// return old value
atomic_add(volatile int *count, int add)
{
#ifdef __linux__
	__asm__ __volatile__(
		"lock xadd %0, (%1);"
		: "=a"(add)
		: "r"(count), "a"(add)
		: "memory"
	);
#else
#error "not done yet "
#endif
	return add;
}
#define nop()						    __asm__ ("pause" )
#define thread_yield		sched_yield
inline void sched_yield()
{  Sleep(1);   }
struct futex {
	volatile int lock;
	volatile int count;
};

#define LARGE_ENOUGH_NEGATIVE			-0x7fffffff

#ifdef	__cplusplus
extern "C" {
#endif

static inline void
futex_init(struct futex* pf, int count)
{
	pf->lock = 0;
	pf->count = count;
}

/* Return value:
 *         0: okay
 * ETIMEDOUT: timeout
 *     EINTR: interrupted
 */
static inline int 
futex_sema_down(struct futex* pf, struct timespec* timeout, bool interruptable)
{
	int n = atomic_add(&pf->count, -1);
	if (n <= 0) {
retry:
        if (0 == sys_futex(&pf->lock, FUTEX_WAIT, 0, timeout)) {
			return 0;
        }

		switch (errno) {
		case ETIMEDOUT: 
			atomic_add(&pf->count, 1); 
			return ETIMEDOUT;
		case EINTR: 
			if (!interruptable)
				goto retry;
			atomic_add(&pf->count, 1); 
			return EINTR;
		default:
			RaiseError(IMPOSSIBLE__Can_not_lock_in_futex_sema_down);
		}
	}
	return 0;
}

/* Return value:
 *  1: wake up some waiter
 *  0: none is waiting
 */
static inline int
futex_sema_up(struct futex* pf)
{
	int retry;
    int n = atomic_add(&pf->count, 1);
	if (n < 0) {
        retry = 10;
		while (1 != (n=sys_futex(&pf->lock, FUTEX_WAKE, 1, NULL))) {
			/* it means the downer decreases the count but not yet start waiting 
			 *   --- may be interrupted near the retry label in the above function;
			 * so we have to wait and retry.
			 */
            if (retry --) { 
                nop(); 
            } 
            else { 
                retry = 10; 
                thread_yield();
            }
		}
		return n;
	}
	return 0;
}


             Review一位同事的代码时候看到16行这样的pause指令,颇感兴趣,关注一下用法。

  1. pause指令提升了自旋等待循环(spin-wait loop)的性能。当执行一个循环等待时,Intel P4或Intel Xeon处理器会因为检测到一个可能的内存顺序违规(memory order violation)而在退出循环时使性能大幅下降。PAUSE指令给处理器提了个醒:这段代码序列是个循环等待。处理器利用这个提示可以避免在大多数情况下的内存顺序违规,这将大幅提升性能。因为这个原因,所以推荐在循环等待中使用PAUSE指令。
  2. pause的另一个功能就是降低Intel P4在执行循环等待时的耗电量。Intel P4处理器在循环等待时会执行得非常快,这将导致处理器消耗大量的电力,而在循环中插入一个pause指令会大幅降低处理器的电力消耗。
  3. pause指令虽然是在Intel P4处理器开始出现的,但是它可以向后与所有的IA32处理器兼容。在早期的IA32 CPU中,pause就像NOP指令。Intel P4和Intel Xeon处理器将pause实现成一个预定义的延迟(pre-defined delay)。这种延迟是有限的,而且一些处理器可以为0。pause指令不改变处理器的架构状态(也就是说,它实际上只是执行了一个延迟——并不做任何其他事情——的操作)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值