Linux 并发访问x86-64上非共享缓存中同一缓存线中的元素

Linux 并发访问x86-64上非共享缓存中同一缓存线中的元素,linux,concurrency,x86-64,cache-control,Linux,Concurrency,X86 64,Cache Control,假设我有以下代码: int x[200]; void thread1() { for(int i = 0; i < 100; i++) x[i*2] = 1; } void thread2() { for(int i = 0; i < 100; i++) x[i*2 + 1] = 1; } intx[200]; void thread1(){ 对于(int i=0;i

假设我有以下代码:

int x[200];

void thread1() {
  for(int i = 0; i < 100; i++)
    x[i*2] = 1;
}

void thread2() {
  for(int i = 0; i < 100; i++)
    x[i*2 + 1] = 1;
}
intx[200];
void thread1(){
对于(int i=0;i<100;i++)
x[i*2]=1;
}
无效线程2(){
对于(int i=0;i<100;i++)
x[i*2+1]=1;
}
假设页面在Linux中配置了默认写缓存策略,那么x86-64内存模型中的代码是否正确(据我所知)?这类代码对性能有什么影响(据我所知-无)

至于表演,我最感兴趣的是沙桥


编辑:如预期-我想从不同线程写入对齐的位置。我希望完成后的上层代码和barrier在
x
中包含
{1,1,1,…}
,而不是
{0,1,0,1,…}
{1,0,1,0,…}

,如果我正确理解的话,写操作最终将通过监听请求传播。Sandy Bridge在核心之间使用快速路径,因此窥探不会击中FSB,但会使用更快的互连。由于它不是基于写入时的缓存失效,所以应该“相当”快,尽管我无法找到冲突解决的开销(但可能低于L3写入)


编辑:根据clean hit的影响为43个周期,dirty hit的影响为60个周期(相比之下,L1的正常开销为4个周期,L2为12个周期,L3为26-31个周期)。

如果我理解正确,写入操作最终将通过窥探请求传播。Sandy Bridge在核心之间使用快速路径,因此窥探不会击中FSB,但会使用更快的互连。由于它不是基于写入时的缓存失效,所以应该“相当”快,尽管我无法找到冲突解决的开销(但可能低于L3写入)


编辑:根据clean hit影响43个周期,dirty hit影响60个周期(相比之下,L1的正常开销为4个周期,L2为12个周期,L3为26-31个周期)。

“代码正确吗”意味着您对它有一些期望。那些是什么?元素是否只写(显然是)?还有谁在读它们,它们是对两个还是一次只读一个?是否存在确定性模式?请详细说明。@Michael Foukarakis:我有许多线程写入到不同的位置(线程是独立的,不写入到完全相同的位置,也不读取数据)。我希望确保缓存一致性(检查x86)和Sandy Bridge上的性能(检查快速路径)。我希望编辑解释了我的期望(这部分是为了确保我忘记了一些事情,因为我对缓存一致性非常确信——但最好是安全的,然后再抱歉)。@Maciej SandyBridge是DMI,不是QPI,Nehalem是QPI。@Marcin:从我理解的角度来看,就处理器的“外部”而言,你是对的。在戒指中,SB使用“增强”QPI(该页面是从维基百科链接的,所以我认为它是正确的-)@Maciej,那么什么是“外部”与“内部”呢?其他内核的缓存是否考虑在内部,但PCI-e总线是外部,还是更复杂的东西?“代码是否正确”意味着您对它有一些期望。那些是什么?元素是否只写(显然是)?还有谁在读它们,它们是对两个还是一次只读一个?是否存在确定性模式?请详细说明。@Michael Foukarakis:我有许多线程写入到不同的位置(线程是独立的,不写入到完全相同的位置,也不读取数据)。我希望确保缓存一致性(检查x86)和Sandy Bridge上的性能(检查快速路径)。我希望编辑解释了我的期望(这部分是为了确保我忘记了一些事情,因为我对缓存一致性非常确信——但最好是安全的,然后再抱歉)。@Maciej SandyBridge是DMI,不是QPI,Nehalem是QPI。@Marcin:从我理解的角度来看,就处理器的“外部”而言,你是对的。在戒指中,SB使用“增强”QPI(该页面是从维基百科链接的,所以我认为它是正确的-)@Maciej,那么什么是“外部”与“内部”呢?其他内核的缓存是在内部考虑的,而PCI-e总线是在外部考虑的,还是更复杂的?