Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 做C++;条件语句携带从条件表达式到语句的依赖关系?_C++_C++11_Memory Model - Fatal编程技术网

C++ 做C++;条件语句携带从条件表达式到语句的依赖关系?

C++ 做C++;条件语句携带从条件表达式到语句的依赖关系?,c++,c++11,memory-model,C++,C++11,Memory Model,我问的是记忆模型意义上的问题 我这样问是因为我想知道我是否可以在下面使用std::memory\u order\u consume: MLOCALEMPTR1和2以及mAtomicMemPtr是指向共享缓冲区的指针 在制作线程中,我正在做: for (int x = 0; x < 10; ++x) { ++mLocalMemPtr1 *mLocalMemPtr1 = x; // <========= A mAtomicMemPtr.store(mL

我问的是记忆模型意义上的问题

我这样问是因为我想知道我是否可以在下面使用
std::memory\u order\u consume

MLOCALEMPTR1和2以及mAtomicMemPtr是指向共享缓冲区的指针

在制作线程中,我正在做:

for (int x = 0; x < 10; ++x)
{
    ++mLocalMemPtr1
    *mLocalMemPtr1 = x;       // <========= A
    mAtomicMemPtr.store(mLocalMemPtr1, std::memory_order_release);
}
for(int x=0;x<10;++x)
{
++MLOCAMPTR1
*mLocalMemPtr1=x;//测试->doSomeLongRunningThing


我特别担心
B
可能在
A
之前执行。我知道我可以使用
std::memory\u order\u acquire
,但我可以使用consume(更轻量级)如果条件语句导致内存顺序依赖。

我认为,使用
消费
顺序,编译器实际上可以提前复制整个
mSharedBuffer
。您需要
acquire
语义来使先前缓存的变量副本无效,而不是
mAtomicMemLocPtr
.

发布消费订单

如果线程A中的原子存储被标记为std::memory\u order\u release,线程B中来自同一变量的原子加载被标记为std::memory\u order\u consume,则所有内存写入(非原子和松弛原子)从线程A的角度来看,在原子存储之前排序的依赖项在线程B中会产生明显的副作用,也就是说,一旦原子加载完成,线程B保证看到线程A写入内存的所有内容,如果它将数据依赖项带入原子加载中

1.10.10:

如果满足以下条件,则评估A在评估B之前排序依赖关系

-A对原子对象M执行释放操作,在另一个线程中,B对M执行消耗操作,读取以A(…)为首的释放序列中由任何副作用写入的值

1.10.9:

如果-A的值用作B的操作数,则计算A与计算B具有相关性,除非:

-B是对std::kill_依赖项(29.3)的任何专门化的调用,或

-A是内置逻辑AND(&&,请参见5.14)或逻辑or(| |,请参见5.15)运算符的左操作数,或

-A是条件(?:,请参见5.16)运算符的左操作数,或

-A是内置逗号(,)运算符(5.18);(…)的左操作数

基于这些事实,我说应该同步
mlocalemptr2
。但是仍然存在评估顺序的问题

if (atomic.load(std::consume) < x)
if(原子负载(标准::消耗)
首先计算哪一个是未指定的。无法保证(因为我在标准中找不到它)编译器将首先执行消耗操作,刷新共享缓冲区,然后加载原子,然后加载


未找到操作数在“期望”中求值的证明顺便说一句,如果没有对原子负载的显式分解,
mlocalemptr2
,它将无法工作,CPU可能会读取
mlocalemptr2
memory\u order\u acquire
指出的内存的陈旧值,在这里不会有太大变化,因为
mlocalemptr2
带有数据依赖性正如在中所述,那么我要说

tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
将依赖项带入循环的条件(将其视为布尔变量标志)。但该条件不会在任何循环体操作中作为操作数读取(也不会写入循环体中另一个操作读取的对象)。因此,需要一个acquire操作,以便使在发布之前排序的操作也发生在acquire之后的操作(即读写发布)之前,而不依赖于使用操作和循环体中的操作之间的数据依赖关系

可能涉及发布-消费语义的解决方案是:

tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
while (tempMemPtr != mLocalMemPtr2)
{
    mLocalMemPtr2 = tempMemPtr; // that line adds the dependency needed 
    ++mLocalMemPtr2;
    int test = *mLocalMemPtr2;
    doSomeLongRunningThing(test);
    tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
}
tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
while (tempMemPtr != mLocalMemPtr2)
{
    mLocalMemPtr2 = tempMemPtr; // that line adds the dependency needed 
    ++mLocalMemPtr2;
    int test = *mLocalMemPtr2;
    doSomeLongRunningThing(test);
    tempMemPtr = mAtomicMemPtr.load(std::memory_order_consume);
}