如何确保在互斥锁期间由多个CPU内核写入的数据在所有内核的所有L1缓存中同步?我不是在谈论代表锁的变量,我在谈论锁中涉及的内存位置。
这适用于Linux,x86_64,我的代码是:
#include <sys/types.h>
#include "dlog.h"
uint *dlog_line;
volatile int dlog_lock;
char *dlog_get_new_line(void) {
uint val;
while(!__sync_bool_compare_and_swap(&dlog_lock, 0, 1)) {
val=*dlog_line;
if (val==DT_DLOG_MAX_LINES) val=0;
*dlog_line=val;
}
dlog_lock = 0;
}
这里,在dlog_get_new_line()函数中,我使用gcc内置函数,因此获取锁定应该没有任何问题。但是,如何确保在释放锁定时,* dlog_line指向的值会传播到系统中所有其他CPU核心的所有L1缓存中?
我不使用pthread,每个进程在不同的cpu核心上运行。
答案 0 :(得分:3)
您感兴趣的内容称为cache coherence。 这是由硬件自动完成的。
简而言之,如果您正确使用__sync_bool_compare_and_swap()
(或任何其他锁定内在函数),则无需执行任何操作。
作为一个过度解释的解释,线程将不会从对__sync_bool_compare_and_swap()
的调用返回,直到所有其他处理器都能够看到新值或者知道他们的本地副本已过期。
如果您对下面(在硬件中)发生的事情感兴趣,可以使用各种缓存一致性算法来确保核心不会读取过时的数据副本。
以下是常用教学协议的部分列表:
答案 1 :(得分:0)
Gcc还有另外两个内置版,它们是为您描述的目的而发明的:__sync_lock_test_and_set
和__sync_lock_release
。它们具有所谓的获取/释放语义,可以保证在保持自旋锁时,您需要的其他变量的存储值是可见的。这些要求比__sync_bool_compare_and_swap
提供的要弱一些,因此最好使用为工作量身定制的工具。
他们应该很好地适应不同硬件的容量。例如,在我的x86_64上,这会将最终原子存储区之前的mfence
指令放入dlog_lock
,但在不同的硬件上,这将适用于可用的指令集。