问题标签 [memory-barriers]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
opencl - 在 OpenCL 中,mem_fence() 与 barrier() 相比做什么?
不像barrier()
(我想我理解),mem_fence()
不会影响工作组中的所有项目。OpenCL 规范说(第 6.11.10 节),用于mem_fence()
:
订购执行内核的工作项的加载和存储。
(因此它适用于单个工作项)。
但是,与此同时,在第 3.3.1 节中,它说:
在工作项内存中具有加载/存储一致性。
所以在一个工作项中,内存是一致的。
那么什么样的东西mem_fence()
有用呢?它不适用于项目,但在项目中不需要......
请注意,我没有使用原子操作(第 9.5 节等)。mem_fence()
是与这些结合使用的想法吗?如果是这样,我很乐意看到一个例子。
谢谢。
更新:我可以看到它在与 barrier()
(隐含地,因为屏障调用mem_fence()
)一起使用时是如何有用的——但肯定有更多,因为它是单独存在的?
c# - 可以基于 CPU 架构在运行时使用条件代码吗?
我正在使用.Net 4.5(预览... 4 就这个问题而言很好)。我正在做线程工作。
根据我的研究,我知道 x86 CPU 具有强大的内存模型,这意味着写入不会被重新排序。这使得释放锁是安全的。对于内存模型较弱的 Itanium CPU 而言,情况并非如此。
我了解易失性、内存障碍和执行重新排序原则。
理想情况下,如果CPU 是 Itanium,我需要在关键点插入内存屏障,但如果它是 x86,则不需要。是否可以动态地执行此操作,就像 JIT 处理的运行时编译器指令一样?
如果没有,我意识到我需要为这两个平台分别构建。在这种情况下,在没有 2 组 C# 文件的情况下执行此操作的最优雅方法是什么,而只需更改目标?
c# - 延迟加载和Thread.MemoryBarrier的使用
当设计一个引用另一个对象的类时,只在第一次使用它时创建被引用的对象可能是有益的,例如使用延迟加载。
我经常使用这种模式来创建一个延迟加载的属性:
然后我在浏览 BCL 的源代码时遇到了这段代码:
据我所知,这些都不是线程安全的。Encoding
例如,可以创建多个对象。Encoding
我完全明白这一点,并且知道如果创建了一个额外的对象,这不是问题。它是不可变的,很快就会被垃圾收集。
但是,我真的很想了解为什么Thread.MemoryBarrier
有必要以及第二个实现与多线程场景中的第一个实现有何不同。
显然,如果线程安全是一个问题,最好的实现可能是使用Lazy<T>
:
c# - 需要澄清 Thread.MemoryBarrier()
简而言之,来自 O'Reilly 的 C#:
假设方法 A 和 B 在不同的线程上同时运行:
作者说:“障碍 1 和 4 阻止此示例写入“0”。障碍 2 和 3 提供了新鲜度保证:它们确保如果 B 在 A 之后运行,读取 _complete 将评估为真。”
我的问题是:
- 为什么需要屏障 4?屏障 1 还不够?
- 为什么需要 2 和 3 ?
- 据我了解,屏障在其以下指令之后阻止在其位置之前执行指令,我正确吗?
java - 内存屏障和 TLB
内存屏障保证数据缓存是一致的。但是,它是否保证 TLB 是一致的?
我看到一个问题,即在线程之间传递 MappedByteBuffer 时,JVM(java 7 update 1)有时会因内存错误(SIGBUS、SIGSEG)而崩溃。
例如
如果没有 Thread.yield(),我偶尔会在 force()、put() 和 C 的 memcpy() 中崩溃,所有这些都表明我试图非法访问内存。使用 Thread.yield() 我没有遇到问题,但这听起来不是一个可靠的解决方案。
有没有人遇到过这个问题?TLB 和内存屏障有什么保证吗?
编辑:操作系统是 Centos 5.7,我已经看到了 i7 和 Dual Xeon 机器上的行为。
我为什么要这样做?因为写入消息的平均时间为 35-100 ns,具体取决于长度,并且使用普通的 write() 并没有那么快。如果我在当前线程中进行内存映射和清理,这需要 50-130 微秒,使用后台线程来完成主线程交换缓冲区大约需要 3-5 微秒。为什么我需要交换缓冲区?因为我正在写入许多 GB 的数据,而 ByteBuffer 的大小不能超过 2 GB。
c# - 这是对 Thread.MemoryBarrier() 的正确使用吗?
假设我有一个控制某个循环执行的字段:
我有一个线程正在运行,它的代码如下:
现在,另一个线程可能设置shouldRun
为false
,而不使用任何同步机制。
据我了解 Thread.MemoryBarrier(),在 while 循环中进行此调用将阻止我的工作线程获取 的缓存版本shouldRun
,并有效地防止发生无限循环。
我对 Thread.MemoryBarrier 的理解是否正确?鉴于我有可以设置shouldRun
变量的线程(这不容易更改),这是确保我的循环一旦shouldRun
被任何线程设置为 false 就会停止的合理方法吗?
c++ - 对共享内存的原子访问
我在多个进程之间有一个共享内存,它以某种方式对内存进行交互。前任:
我想要的是让计数器自动更新/递增。并在该地址上发生内存释放。例如,如果我没有使用共享内存,它将类似于
我如何为随机内存位置实现这一点(解释为 DataBlock 计数器 >above)。我可以保证地址按照架构的要求对齐(x86 linux)
- 使更新原子化 - 如何?(即 atomicupdate(addr, newvalue))
- 多核的内存同步 - (即 memorysync(addr)) - 我能看到的唯一方法是使用 std::atomic_thread_fence(std::memory_order_release) - 但这将“建立所有原子和宽松原子存储的内存同步排序” - 就是这样对我来说有点矫枉过正——我只想同步计数器位置。欣赏任何想法。
c++ - 原子的 C++ 内存屏障
在这方面我是新手。任何人都可以提供以下内存屏障之间差异的简化解释吗?
- 窗户
MemoryBarrier();
- 栅栏
_mm_mfence();
- 内联汇编
asm volatile ("" : : : "memory");
- 内在的
_ReadWriteBarrier();
如果没有简单的解释,一些好的文章或书籍的链接可能会帮助我弄清楚。到目前为止,我只使用由其他人编写的包装这些调用的对象很好,但我希望比我目前的想法有更好的理解,这基本上是按照不止一种方法来实现内存屏障的。
multithreading - 如果第二个线程等待第一个线程的终止,是否需要内存屏障?
假设线程Alpha
正在写入变量A
而没有锁定。第二个线程Beta
正在等待Alpha
终止,然后依次读取变量A
。
A
会不会内容不新鲜?内存写入可以延迟到线程生命周期之外吗?等待线程终止的标准机制不会Alpha
隐含地充当内存屏障吗?
更新 1
是否有任何不包括内存屏障的等待示例?
c - 使用标志在线程之间进行通信
在 Internet 上,可以找到许多关于volatile
在并行编程中使用关键字的争论,有时争论不休。
关于这个主题的更值得信赖的讨论之一似乎是Arch Robison 的这篇文章。他使用的示例是将值从一个线程传递到另一个线程的任务:
线程 1. 计算一个矩阵乘积并将其提供给线程 2,线程 2 用它做其他事情。矩阵是可变M
的,标志是volatile
指针R
。
- 线程 1 乘以计算矩阵乘积 M 并以原子方式将 R 设置为指向 M。
- 线程 2 等到 R!=NULL 然后使用 M 作为一个因子来计算另一个矩阵乘积。
换句话说,M 是一条消息,R 是一个就绪标志。
作者声称,虽然将 R 声明为 volatile 将解决将更改从线程 1 传播到线程 2 的问题,但它不能保证发生这种情况时 M 的值是多少。分配给R
和M
可以重新排序。因此,我们需要在 pthreads 之类的库中同时使用M
和R
volatile 或使用一些同步机制。
我的问题是,如何在 C 中执行以下操作
1)如何在两个线程之间共享一个标志 - 如何原子地分配给它,确保另一个线程将看到更改并测试另一个线程中的更改。在这种情况下使用 volatile 合法吗?或者某些库能否提供概念上更好或更快的方法,可能涉及内存屏障?
2)如何正确地执行 Robison 的示例,以及如何将矩阵 M 从一个线程发送到另一个线程并安全地进行(最好使用 pthreads 便携)