相关疑难解决方法(0)

C++ 11引入了标准化的内存模型.这是什么意思?它将如何影响C++编程?

C++ 11引入了标准化的内存模型,但究竟是什么意思呢?它将如何影响C++编程?

这篇文章(引用Herb SutterGavin Clarke)说,

内存模型意味着C++代码现在有一个标准化的库可以调用,无论是谁编译器以及它运行的平台.有一种标准方法可以控制不同线程与处理器内存的对话方式.

"当你谈论在标准中的不同内核之间分割[代码]时,我们正在谈论内存模型.我们将优化它,而不会破坏人们将在代码中做出的以下假设," Sutter说.

好吧,我可以在网上记住这个和类似的段落(因为我从出生以来就拥有自己的记忆模型:P),甚至可以发布作为其他人提出的问题的答案,但说实话,我并不完全明白这个.

C++程序员以前用于开发多线程应用程序,那么如果它是POSIX线程,Windows线程或C++ 11线程,它又如何重要呢?有什么好处?我想了解低级细节.

我也觉得C++ 11内存模型与C++ 11多线程支持有某种关系,因为我经常将这两者结合在一起.如果是,究竟是怎么回事?他们为什么要相关?

由于我不知道多线程的内部工作原理以及内存模型的含义,请帮助我理解这些概念.:-)

c++ multithreading memory-model language-lawyer c++11

1810
推荐指数
7
解决办法
21万
查看次数

同时访问Java中同一对象的不同成员

我熟悉Java中许多围绕并发的机制和习惯用法.我困惑的地方是一个简单的概念:同一对象的不同成员的并发访问.

我有一组可由两个线程访问的变量,在这种情况下涉及游戏引擎中的图形信息.我需要能够在一个线程中修改对象的位置并在另一个线程中读取它.解决此问题的标准方法是编写以下代码:

private int xpos;
private object xposAccess;

public int getXpos() {
    int result;
    synchronized (xposAccess) {
        result = xpos;
    }
    return result;
}

public void setXpos(int xpos) {
    synchronized (xposAccess) {
        this.xpos = xpos;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我正在编写一个实时游戏引擎,而不是一个20个问题的应用程序.我需要快速工作,特别是当我访问和修改它们时,就像我处理图形资产的位置一样.我想删除同步开销.更好的是,我想完全删除函数调用开销.

private int xpos;
private int bufxpos;
...

public void finalize()
{
    bufxpos = xpos;
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用锁,我可以使线程彼此等待,然后调用finalize(),同时既不访问也不修改对象.在这个快速缓冲步骤之后,两个线程都可以自由地操作对象,一个修改/访问xpos,一个访问bufxpos.

我已经成功地使用了类似的方法,其中信息被复制到第二个对象,并且每个线程作用于单独的对象.但是,两个成员仍然是上述代码中同一个对象的一部分,当我的线程同时访问对象时,即使在对不同的成员进行操作时,也会发生一些有趣的事情.不可预知的行为,幻像图形对象,屏幕位置的随机错误等.为了验证这确实是一个并发问题,我在一个线程中运行了两个线程的代码,在那里它执行完美.

我希望性能高于一切,我正在考虑缓存关键数据以分离对象.我的错误是由并发访问相同对象引起的吗?是否有更好的并发解决方案?

编辑:如果你怀疑我的表现估价,我应该给你更多的背景.我的引擎是为Android编写的,我使用它来绘制数百或数千个图形资源.我有一个单线程解决方案,但是自从实现多线程解决方案以来,我看到性能几乎翻了一番,尽管存在幻像并发问题和偶尔的未捕获异常.

编辑:感谢关于多线程性能的精彩讨论.最后,我能够通过在工作线程处于休眠状态时缓冲数据来解决问题,然后允许它们在对象内的每个数据集进行操作.

java performance multithreading android

9
推荐指数
1
解决办法
1601
查看次数

易失性关键字和内存一致性错误

此处的oracle Java文档中,如下所示:

原子动作不能交错,因此可以使用它们而不必担心线程干扰.但是,这并不能消除所有同步原子操作的需要,因为仍然可能存在内存一致性错误.使用volatile变量可降低内存一致性错误的风险,因为对volatile变量的任何写入都会建立与之后读取同一变量的先发生关系.这意味着对volatile变量的更改始终对其他线程可见.更重要的是,它还意味着当线程读取volatile变量时,它不仅会看到volatile的最新更改,还会看到导致更改的代码的副作用.

它还说:

  • 读取和写入对于引用变量和大多数原始变量(除long和double之外的所有类型)都是原子的.
  • 对于声明为volatile的所有变量(包括长变量和双变量),读取和写入都是原子的.

关于这些陈述,我有两个问题:

  1. "使用volatile变量降低了内存一致性错误的风险" - 它们的意思是"降低风险",以及在使用volatile时如何仍然可以实现内存一致性错误?

  2. 如果将volatile放在非双非长基元上的唯一效果是,是否能够与其他线程的后续读取启用"先发生"关系?我问这个,因为这些变量似乎已经有了原子读数.

java multithreading volatile

7
推荐指数
1
解决办法
1187
查看次数