Questions tagged «memory-model»

8
C ++ 11引入了标准化的内存模型。这是什么意思?它将如何影响C ++编程?
C ++ 11引入了标准化的内存模型,但这究竟意味着什么?它将如何影响C ++编程? 这篇文章(由加文·克拉克(Gavin Clarke)引用赫伯·萨特(Herb Sutter)表示)说, 内存模型意味着C ++代码现在有一个标准化的库可以调用,而不管编译器的创建者和运行平台是什么。有一种标准方法可以控制不同线程如何与处理器的内存通信。 “当你在谈论分裂[代码]在不同的内核,就是在标准,我们正在谈论的内存模型。我们要优化它没有打破以下假设人会在代码中做出,” 萨特说。 好吧,我可以记住这一段以及网上可以找到的类似段落(因为我从出生就拥有自己的记忆模型:P),甚至可以发布它作为对其他人提出的问题的答案,但是老实说,我并不完全理解这个。 C ++程序员甚至以前都曾开发过多线程应用程序,那么,它是POSIX线程,Windows线程还是C ++ 11线程又有什么关系呢?有什么好处?我想了解底层细节。 我还感觉到C ++ 11内存模型与C ++ 11多线程支持某种程度上相关,因为我经常将两者结合在一起。如果是的话,究竟如何?为什么要关联它们? 由于我不了解多线程的内部原理以及内存模型的一般含义,请帮助我理解这些概念。:-)



3
C是否与C ++具有等效的std :: less?
我最近在回答一个关于p < q当p和q是指向不同对象/数组的指针时在C 中执行的未定义行为的问题。这让我想到:C ++ <在这种情况下具有相同(未定义)的行为,但是还提供了标准库模板std::less,该模板保证可以返回与<可以比较指针时相同的东西,并在不能比较时返回一些一致的顺序。 C是否提供具有类似功能的东西,从而可以安全地比较任意指针(相同类型)?我尝试浏览C11标准并没有发现任何东西,但是我在C中的经验比在C ++中小得多,因此我很容易错过一些东西。

1
Java中的内存防护有什么用?
在尝试了解如何实现SubmissionPublisher(Java SE 10中的源代码,OpenJDK | docs),在版本9中添加到Java SE的新类的实现之后,我偶然发现了一些VarHandle以前没有意识到的API调用: fullFence,acquireFence,releaseFence,loadLoadFence和storeStoreFence。 在进行了一些研究之后,尤其是关于内存屏障/栅栏的概念(我以前听说过,是的;但是从未使用过它们,因此对它们的语义非常陌生),我认为我对它们的用途有基本的了解。 。但是,由于我的问题可能是由错误的观念引起的,因此我想确保我一开始就正确: 内存障碍是关于读写操作的重新排序约束。 内存屏障可以分为两大类:单向和双向内存屏障,取决于它们是对读取还是写入或对这两者设置约束。 C ++支持多种内存屏障,但是这些屏障与所提供的屏障不匹配VarHandle。然而,一些在可用内存壁垒VarHandle提供排序的影响是兼容其相应的C ++内存屏障。 #fullFence 与...兼容 atomic_thread_fence(memory_order_seq_cst) #acquireFence 与...兼容 atomic_thread_fence(memory_order_acquire) #releaseFence 与...兼容 atomic_thread_fence(memory_order_release) #loadLoadFence并且#storeStoreFence没有兼容的C ++计数器部分 “ 兼容 ”一词在这里似乎非常重要,因为在细节上语义明显不同。例如,所有C ++障碍都是双向的,而Java障碍不是必需的。 大多数内存屏障也具有同步效果。这些特别取决于其他线程中使用的屏障类型和先前执行的屏障指令。由于障碍指令的全部含义是特定于硬件的,因此我将坚持使用更高级别的(C ++)障碍。在C ++中,例如,改变由之前的释放屏障指令是执行一个线程可见获取屏障指令。 我的假设正确吗?如果是这样,我的问题是: 可用的内存屏障是否VarHandle会引起任何类型的内存同步? 无论它们是否引起内存同步,重新排序约束在Java中可能有什么用?Java内存模型已经就可变字段,锁或VarHandle类似操作的顺序提供了一些非常有力的保证#compareAndSet。 如果您正在寻找一个示例:前面提到BufferedSubscription的SubmissionPublisher(内部链接为的内部类)在第1079行中建立了完整的围栏(功能growAndAdd;由于链接的网站不支持片段标识符,因此仅需使用CTRL + F )。但是,我不清楚它的用途。

1
C11原子获取/发布和x86_64缺乏加载/存储一致性?
我在C11标准的5.1.2.4节中苦苦挣扎,尤其是Release / Acquire的语义。我注意到https://preshing.com/20120913/acquire-and-release-semantics/(以及其他)指出: ...释放语义可防止以程序顺序在写释放之前进行任何读或写操作,从而对写释放进行内存重新排序。 因此,对于以下情况: typedef struct test_struct { _Atomic(bool) ready ; int v1 ; int v2 ; } test_struct_t ; extern void test_init(test_struct_t* ts, int v1, int v2) { ts->v1 = v1 ; ts->v2 = v2 ; atomic_store_explicit(&ts->ready, false, memory_order_release) ; } extern int test_thread_1(test_struct_t* ts, int v2) { …

1
“在此之前发生”是什么意思?
在C ++草案标准中多次使用“强烈发生于”这一短语。 例如:终止 [basic.start.term] / 5 如果具有静态存储持续时间的对象的初始化强烈发生在对std :: atexit的调用之前(请参见[support.start.term]),则对该函数的调用将传递给std :: atexit在调用对象的析构函数之前进行排序。如果对std :: atexit的调用强烈发生在具有静态存储持续时间的对象的初始化完成之前,则在调用传递给std :: atexit的函数之前对对象的析构函数的调用进行排序。如果对std :: atexit的调用在另一次对std :: atexit的调用之前强烈发生,则传递给第二个std :: atexit的函数的调用在传递给第二个std :: atexit的函数之前被排序。第一个std :: atexit调用。 并在 数据竞赛 [intro.races] / 12中定义 评估A发生在评估D之前,如果发生以下情况之一 (12.1)A在D之前排序,或 (12.2)A与D同步,并且A和D都是顺序​​一致的原子操作([atomics.order]),或 (12.3)对B和C进行求值,使得A在B之前排序,B仅发生在C之前,而C在D之前排序,或者 (12.4)有一个评估B,使得A强烈发生在B之前,而B强烈发生在D之前。 [注意:非正式地,如果A强烈地发生在B之前,那么在所有情况下A似乎都在B之前被评估。强烈发生在排除消耗操作之前。—尾注] 为什么引入“强烈发生”?直觉上,它与“之前发生的事情”有什么区别和关系? 注释中的“在所有情况下,似乎A在B之前都被评估”是什么意思? (注意:此问题的动机是Peter Cordes在此答案下的评论。) 标准报价附加草案(感谢Peter Cordes) 有序性和一致性[atomics.order] / 4 所有memory_order :: seq_cst操作(包括篱笆)上都有一个总顺序S,它满足以下约束。首先,如果A和B是memory_order ::: seq_cst运算,并且A强烈地发生在B之前,那么A在S中先于B.其次,对于对象M上的每对原子操作A和B,A的相干性在B之前,S必须满足以下四个条件: …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.