新的c ++标准引入了内存模型的概念.关于它的问题已经有了问题,它是什么意思,它如何改变我们用c ++编写代码的方式等等.
我有兴趣了解C++内存模型与旧的,众所周知的Java内存模型(1.5)的关系.它是一样的吗?它是相似的吗?他们有什么重大差异吗?如果是这样,为什么?
java内存模型已经存在很长时间了很多人都知道它非常不错,所以我想通过比较它来学习C++内存模型可能会有所帮助.
if (var != X)
var = X;
Run Code Online (Sandbox Code Playgroud)
是明智还是不合理?编译器是否总是优化if语句?是否有任何用例可以从if语句中受益?
如果var是volatile变量怎么办?
我对C++和Java答案感兴趣,因为volatile变量在两种语言中都有不同的语义.Java的JIT编译也可以带来改变.
如果我们总是用X覆盖var,那么if语句会引入分支和附加读取,所以它很糟糕.另一方面,如果var == X然后使用此优化,我们只执行读取,并且我们不执行写入,这可能会对缓存产生一些影响.显然,这里有一些权衡.我想知道它在实践中的样子.有没有人对此做过任何测试?
编辑:
我最感兴趣的是它在多处理器环境中的样子.在一个微不足道的情况下,首先检查变量似乎没有多大意义.但是,当处理器/核心之间必须保持高速缓存一致性时,额外检查可能实际上是有益的.我只是想知道它会产生多大的影响?处理器本身也不应该做这样的优化吗?如果var == X再次分配它值X不应该"弄脏"缓存.但我们可以依靠这个吗?
我有一个由链接节点组成的数据结构.您可以将其视为简单的LinkedList.列表的每个节点由一些值和指向另一个节点的下一个字段组成,如果它是最后一个节点则为null.第一个节点作为根,它没有值,只指向下一个节点.所有其他节点实际上是不可变的,一旦它们被创建,它们的值和它们的下一个字段在生命期间都不会改变,除非正在处理与特定情况有关的结构.
一个(仅一个)线程将新节点添加到列表的前面.它是通过构造一个新对象,设置其字段并将下一个字段设置为根指向的对象,然后将根的下一个字段设置为此新节点来实现的.
其他节点浏览仅执行读取的结构.它们具有对根节点的引用,然后它们通过其他节点,直到找到正在查找的内容或到达列表的末尾.
我的问题是:是否足以使下一个字段变得易变?根据我对java内存模型的理解,如果主线程(添加新节点的线程)在添加新节点时将执行易失性写入,那么一切都将很好地同步,并且不会发生任何不一致.
也是正确的假设在x86架构上读取volatile变量不会导致任何性能下降?由于其他线程将经常浏览读取下一个字段的结构,因此可以自由地完成此操作而不需要任何内存屏障等.
我还有一个问题.要浏览结构的线程也将保留一些额外的节点.这些节点将完全是线程本地的,它们将仅由创建它们的线程使用,并且根本不会被共享.对于这些附加节点,下一个字段不必是易失性的.此外,设置易失性下一字段将发出存储器屏障,这将导致不期望的性能损失.我想知道有没有办法避免这种情况.理想情况下,如果下一个字段有时会作为一个易失性字段而有时作为一个普通字段工作,那将是完美的;)或者如果我有完全控制并且可以在我需要的时候自行发出内存屏障.
编辑:
我还想知道是否有可能以不同的方式将所有这些写入同步到不同的volatile变量上?例如一些其他完全不相关的静态变量?由于volatile写入刷新所有挂起的写入,下一个字段是不是可能不是易失性的,而是在更新线程完成所有工作后会写入不同的volatile变量?
它对我来说看起来不太安全,因为在关系之前没有发生,之前的写入可能会被重新排序.可以使用值字段分配重新下载下一个字段分配,从而导致迭代线程观察到不一致的对象状态.
但也许有可能提出这样一个安全的方案吗?这个怎么样:
更新线程首先构造一个新对象,初始化其值字段,将其下一个字段设置为根节点指向的节点,对某个静态变量执行易失性写入,将根节点的下一个字段设置为新创建的节点
我有一组实体,我需要将这些实体分组调用specie.所有物种定义的呼叫集合Universe和实体必须属于一个且仅属于一个物种.为此,我有一个布尔不及物函数调用f,如果两个实体通过参数传递兼容,则返回.A specie由一组彼此兼容的实体universe定义,并且a 由一组彼此不完全兼容的物种定义,假设两个物种的相容性由其所有实体的兼容性定义.
如何确定包含给定实体集可能的最小物种数的Universe?
我尝试如下,我的函数返回一个有效的宇宙,但不是具有最小物种数的宇宙.
public class Specie {
private List<Entity> individuals;
public Specie() {
this.individuals = new ArrayList<>();
}
public boolean matches(Entity e) {
for (Entity s : this.individuals) {
if (!f(s, e)) {
return false;
}
}
return true;
}
public void add(Entity i) {
this.individuals.add(i);
}
}
private static int numberOfSpeciesRecursive(List<Entity> entities, List<Specie> universe) {
if (entities.size() == 0) {
return 0;
} else {
List<Entity> remains = …Run Code Online (Sandbox Code Playgroud) java ×4
c++ ×2
algorithm ×1
c++11 ×1
caching ×1
combinations ×1
concurrency ×1
grouping ×1
memory-model ×1
optimization ×1
performance ×1
volatile ×1