samedi 30 juillet 2016

Is there any effect on the operations with the variables independent of consume atomic-load?

As known, there are 6 std::memory_order's, and 2 of its:

  • acquire-semantic used for loads - avoids reordering Load-Load and Load-Store
  • release-semantic used for stores - avoids reordering Store-Store and Load-Store

enter image description here

I.e. for acquire-semantic, only S = local1; can be executed after X.load(std::memory_order_acquire);:

static std::atomic<int> X;
static int L, S;
...

void thread_func() 
{
    int local1 = L;  // load(L)-load(X) - can't be reordered with X
    S = local1;      // store(S)-load(X) - !!! can be reordered with X !!!

    int x_local = X.load(std::memory_order_acquire);  // load(X)

    int local2 = L;  // load(X)-load(L) - can't be reordered with X
    S = local2;      // load(X)-store(S) - can't be reordered with X
}

But which of reorders across load(X) can be for consume-semantic?

static std::atomic<int> *X;
static int L1, L2, S1, S2;
static int L, S;
...

void thread_func() 
{
    int *x_ptr_local = new int(1);


    int local1 = L1;  // load(L1)-load(X) - !!! can be reordered with X !!!
    S1 = local1;      // store(S1)-load(X) - !!! can be reordered with X !!!

    int dependent_x1 = *x_ptr_local;  // load(x_ptr)-load(X) - can't be reordered with X
    S = dependent_x1;                 // store(S)-load(X) - can't be reordered with X

    x_ptr_local = X.load(std::memory_order_consume);  // load(X)

    int dependent_x2 = *x_ptr_local;  // load(X)-load(x_ptr) - can't be reordered with X
    S = dependent_x2;                 // load(X)-store(S) - can't be reordered with X

    int local2 = L2;  // load(X)-load(L2) - !!! can be reordered with X !!!
    S2 = local2;      // load(X)-store(S2) - !!! can be reordered with X !!!
}

Is it true, that only operations with dependent_x1 and dependent_x2 can't be reordered across X.load(std::memory_order_consume)?

And all of operations with variables L1, L2, S1, S2 can be reordered across X.load(std::memory_order_consume) - i.e. can be performed either before or after X.load(std::memory_order_consume), isn't it?

Aucun commentaire:

Enregistrer un commentaire