请使用OpenMP进行并行化,查看以下代码段:
char lock = 0;
#pragma omp parallel
{
while(!__sync_bool_compare_and_swap(&lock, 0, 1));
printf("Thread: %d is working!\n", omp_get_thread_num());
sleep(1);
printf("Thread: %d unlocks lock!\n", omp_get_thread_num());
lock = 0;
}
是否可能,线程同时锁定锁,即使使用__sync_bool_compare_and_swap锁定是原子的? 例如,并非所有线程都具有一致的内存视图?
答案 0 :(得分:3)
如果您坚持不以OpenMP方式执行此操作:
您肯定需要编译器屏障来阻止lock=0
成为reordered at compile time。
如果你只是针对x86,那么编译屏障就可以了;否则在lock=0
之前使用C11 atomic_thread_fence(memory_order_release)
,这只是x86上的编译器屏障,但会在弱有序体系结构上发出必要的指令。
或者使lock
为原子类型,并使用C11 stdatomic release-store将其设置为0.
在lock cmpxchg
上旋转以获取锁定是非常低效的。您应该旋转一个负载,直到锁定可用,然后尝试接受它。例如你应该编写一些可以编译成代码like this minimal but real asm spinlock implementation.
e.g。使用memory_order_acquire
的C11原子载荷。然后使用普通xchg
,而不是cmpxchg
,并检查您是否获得了锁定,或者在您执行此操作之前是否有其他线程接受了锁定。