Tag: memory barriers

乱序执行和记忆围栏

我知道现代CPU可以无序执行,但是他们总是按顺序退出结果,如维基百科所述。 “Out of Oder处理器及时填写这些”插槽“和其他准备就绪的指令, 然后在结束时重新排序结果,使其看起来正常处理指令。 ” 现在,在使用多核平台时,据说需要内存栅栏,因为由于乱序执行,可以在此处打印错误的x值。 Processor #1: while f == 0 ; print x; // x might not be 42 here Processor #2: x = 42; // Memory fence required here f = 1 现在我的问题是,由于乱序处理器(我假设MultiCore处理器的情况下的核心)总是按顺序退出结果,那么内存栅栏的必要性是什么。 难道多核处理器的核心不会看到仅从其他核心退役的结果,或者它们是否也会看到正在进行中的结果? 我的意思是在我上面给出的例子中,当处理器2最终将结果退出时, x的结果应该在f之前,对吧? 我知道在乱序执行期间它可能在x之前修改了f但是它必须在x之前没有退出它,对吗? 现在有了按顺序退出结果和缓存一致性机制,为什么你需要在x86中使用内存栅栏?

使用时间戳计数器和clock_gettime进行缓存未命中

作为本主题的后续内容 ,为了计算内存未命中延迟,我使用_mm_clflush , __rdtsc和_mm_lfence (基于此问题/答案的代码)编写了以下代码。 正如您在代码中看到的,我首先将数组加载到缓存中。 然后我刷新一个元素,因此缓存行从所有缓存级别逐出。 为了在-O3期间保留顺序,我放了_mm_lfence 。 接下来,我使用时间戳计数器来计算延迟或读取array[0] 。 正如您在两个时间戳之间看到的那样,有三个指令:两个lfence和一个read 。 所以,我必须减去lfence开销。 代码的最后一部分计算开销。 在代码结束时,打印开销和未命中延迟。 但是,结果无效! #include #include #include int main() { int array[ 100 ]; for ( int i = 0; i < 100; i++ ) array[ i ] = i; uint64_t t1, t2, ov, diff; _mm_lfence(); _mm_clflush( &array[ 0 ] ); _mm_lfence(); […]