memory-barriers相关内容
如果Core写入但其L1中不存在高速缓存行,则它将写入存储缓冲区.另一个核心请求该缓存行,MESI无法看到存储缓冲区更新,并返回未修改的缓存行.此后不久,将刷新存储缓冲区,但是第二个Core已经使用了较早的值. 我看不到SFENCE如何解决此问题?是的,缓存行将尽快更新,但是Core仍然需要等待将该值写入L1,在此期间第二个Core可以请求读取? 解决方案 不,它不会阻止核心“隐藏"
..
说,我有两个线程A和B分别写入全局布尔变量fA和fB,它们最初设置为false并受std::mutex对象mA和mB分别: // Thread A mA.lock(); assert( fA == false ); fA = true; mA.unlock(); // Thread B mB.lock() assert( fB == false ); fB = true; mB.unloc
..
有关内存顺序的cppreference文档说 放松内存排序的典型用法是递增计数器,例如std :: shared_ptr的引用计数器,因为这仅需要原子性,而不需要排序或同步(请注意,递减shared_ptr计数器需要获取释放同步与析构函数) 这是否意味着宽松的内存排序实际上不会导致针对同一变量的原子性?但是,是否最终会导致相对于其他宽松的内存负载和/或compare_exchange的
..
在阅读了更多博客/文章等之后,我现在对于在内存屏障之前/之后加载/存储的行为感到非常困惑. 以下是道格·利阿(Doug Lea)在他有关JMM的澄清文章中的两句话,它们都很简洁: 线程A写入易失性字段f时可见的所有内容在线程B读取f时对线程B可见. 请注意,两个线程访问相同的volatile变量很重要,以便正确设置事前发生的关系.并非所有情况下,线程A写入易失性字段f时对线程A可见的
..
我目前正在阅读Anthony Williams撰写的C ++ Concurrency in Action.他的清单之一显示了此代码,并且他指出z != 0可以触发的断言. #include #include #include std::atomic x,y; std::atomic z; void write
..
在我审阅的代码库中,我发现了以下成语. void notify(struct actor_t act) { write(act.pipe, "M", 1); } // thread A sending data to thread B void send(byte *data) { global.data = data; notify(threadB); } // i
..
我发现x86 CPU具有以下内存屏障指令:mfence,lfence和sfence. x86 CPU仅具有这三个内存屏障指令,还是还有更多? 解决方案 sfence(SSE1)和mfence/lfence(SSE2)是为其内存防护/屏障命名的唯一说明.功能.除非您使用NT加载或存储和/或WC内存,否则只需mfence即可进行内存排序. (请注意,Intel CPU上的 lfen
..
我阅读了《英特尔架构优化指南》. 但是,我仍然不知道何时应该使用 _mm_sfence() _mm_lfence() _mm_mfence() 有人能解释在编写多线程代码时应何时使用这些代码吗? 解决方案 注意事项:我不是这方面的专家.我仍在尝试自己学习.但是,由于过去两天没有人答复,因此关于内存隔离栅指令的专家似乎并不多.所以这是我的理解... 英特尔是弱排序内存系
..
假设线程Alpha在不锁定的情况下正在写入变量A.第二个线程Beta正在等待Alpha终止,然后依次读取变量A. A的内容是否可能不是新鲜的?可以将内存写入延迟到线程生存期之后吗?等待线程Alpha终止的标准机制是否会隐式地充当内存屏障? 更新1 有没有没有记忆障碍的等待示例? 解决方案 几乎可以肯定(用于等待线程终止的API需要出于自身目的使用内存屏障),但是我想为您提
..
在msdn上 http://msdn.microsoft.com/zh-CN/library/windows/desktop/ms684208(v=vs.85).aspx ,MemoryBarrier的实现是对xchg的调用. // x86 FORCEINLINE VOID MemoryBarrier ( VOID ) { LONG Barrier; __
..
我有一个关于内存映射io的问题. 假设有一个内存映射的IO外设,其值正在由CPU读取.读取后,该值将存储在高速缓存中.但是内存中的值已由外部IO外设更新. 在这种情况下,CPU将如何确定缓存已失效,这种情况下的解决方法是什么? 解决方案 这与平台密切相关.实际上,有两种不同的情况. 案例1..内存映射的外围设备.这意味着对某些范围的物理内存地址的访问将路由到外围设备.没有实际的RAM
..
在.NET中,lock关键字是Monitor.Enter和Monitor.Exit周围的语法糖,因此您可以说这段代码 lock(locker) { // Do something } 与 相同 Monitor.Enter(locker); try { // Do Something } finally { Monitor.Exit(locker); } 但是.NET框
..
我一直在阅读内存壁垒:针对软件黑客的硬件视图,这是Paul E的一篇非常受欢迎的文章麦肯尼. 论文强调的一件事是,像Alpha这样的顺序较弱的处理器可以对依赖的负载进行重新排序,这似乎是分区缓存的副作用 论文摘录: 1 struct el *insert(long key, long data) 2 { 3 struct el *p; 4 p = kmalloc(
..
内核源文件Documentation/memory-barriers.txt中有一个插图,如下所示: CPU 1 CPU 2 ======================= ======================= { B = 7; X = 9; Y = 8; C = &Y } STORE A = 1
..
我对以下代码中的操作顺序有疑问: std::atomic x; std::atomic y; int r1; int r2; void thread1() { y.exchange(1, std::memory_order_acq_rel); r1 = x.load(std::memory_order_relaxed); } void thread2() {
..
在本文中内存障碍和JVM并发 !,我被告知volatile是由不同的实现内存屏障指令,同步和原子通过锁定前缀指令实现。但我在其他文章中得到了以下代码: java代码: volatile Singleton instance = new Singleton(); 汇编指令(x86): 0x01a3de1d:movb $ 0x0,0x1104800(%esi); 0x01
..
我正在撰写与深入理解Java中的volatile public class Main { private int x; private volatile int g; public void actor1(){ x = 1; g = 1; } public void actor2(){ put_on_screen_without_sync(g);
..
AFAIK有pthread函数作为内存屏障(例如,这里澄清-上全存储器屏障参与的逐并行线程-互斥)。但编译时障碍,即编译器(特别是gcc)是否意识到这一点? 换句话说 - 例如 - 是pthread_create()gcc不执行重新排序的原因? 例如在代码中: a = 1; pthread_create(...); 确定重新排序不会发生? 如何调用不同
..
考虑下面的 spin_lock()实现,最初来自这个答案 a>: void spin_lock(volatile bool * lock){ for(;;){ //插入获取内存屏障和编译器屏障 if(!__ atomic_test_and_set(lock,__ATOMIC_ACQUIRE)) return; while(* lock)//无障碍;可以吗? cpu_re
..
据我所知, mfence 是一个硬件内存障碍,而 asm volatile(“”:::“memory”)是编译器障碍。但是,可以使用 asm volatile(“”:::“memory”)来代替保护。 我感到困惑的原因是这个链接 x86和x64没有弱内存排序。在x86 / x64上,所有商店都有一个发布栏,所有负载都有一个收购栏。所以,你应该只需要 asm volatile(“”::“
..