• SMR load...

    From Chris M. Thomasson@3:633/10 to All on Wed Oct 14 14:55:22 2026
    Why does the C++ memory model seem to require async SMR loads to
    basically NEED std::memory_order_consume, which iirc gets folded into
    acquire. on the load side of SMR?
    ______________________
    per_node*
    smr_load(
    unsigned long tidx
    ) {
    for (;;)
    {
    per_node* node0 = m_node.load(rl::mo_relaxed, $);

    if (! node0)
    {
    RL_ASSERT(0); // hould never happen in this test!
    m_threads[tidx].m_haz_0.store(nullptr, rl::mo_relaxed, $);
    break;
    }

    m_threads[tidx].m_haz_0.store(node0, rl::mo_relaxed, $);

    // actually, iirc, a single seq_cst right here should work?
    // well, this is an async test...

    per_node* node1 = m_node.load(rl::mo_consume, $);

    // uncomment below, Relacy goes berserker!
    //per_node* node1 = m_node.load(rl::mo_relaxed, $);
    if (node0 == node1)
    {
    return node0;
    }
    }

    return nullptr;
    }
    ______________________


    If I make that mo_consume relaxed, Relacy shits its pants.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Oct 14 15:11:20 2026
    On 10/14/2026 2:55 PM, Chris M. Thomasson wrote:
    Why does the C++ memory model seem to require async SMR loads to
    basically NEED std::memory_order_consume, which iirc gets folded into acquire. on the load side of SMR?


    Pure ISO C++ no longer gives you a way to express ?this load only needs dependency ordering, no full acquire barrier.?

    Sigh.


    ______________________
    ˙per_node*
    ˙smr_load(
    ˙˙˙˙ unsigned long tidx
    ˙) {
    ˙˙˙˙ for (;;)
    ˙˙˙˙ {
    ˙˙˙˙˙˙˙˙ per_node* node0 = m_node.load(rl::mo_relaxed, $);

    ˙˙˙˙˙˙˙˙ if (! node0)
    ˙˙˙˙˙˙˙˙ {
    ˙˙˙˙˙˙˙˙˙˙˙˙ RL_ASSERT(0); // hould never happen in this test!
    ˙˙˙˙˙˙˙˙˙˙˙˙ m_threads[tidx].m_haz_0.store(nullptr, rl::mo_relaxed, $);
    ˙˙˙˙˙˙˙˙˙˙˙˙ break;
    ˙˙˙˙˙˙˙˙ }

    ˙˙˙˙˙˙˙˙ m_threads[tidx].m_haz_0.store(node0, rl::mo_relaxed, $);

    ˙˙˙˙˙˙˙˙ // actually, iirc, a single seq_cst right here should work?
    ˙˙˙˙˙˙˙˙ // well, this is an async test...

    ˙˙˙˙˙˙˙˙ per_node* node1 = m_node.load(rl::mo_consume, $);

    ˙˙˙˙˙˙˙˙ // uncomment below, Relacy goes berserker!
    ˙˙˙˙˙˙˙˙ //per_node* node1 = m_node.load(rl::mo_relaxed, $);
    ˙˙˙˙˙˙˙˙ if (node0 == node1)
    ˙˙˙˙˙˙˙˙ {
    ˙˙˙˙˙˙˙˙˙˙˙˙ return node0;
    ˙˙˙˙˙˙˙˙ }
    ˙˙˙˙ }

    ˙˙˙˙ return nullptr;
    ˙}
    ______________________


    If I make that mo_consume relaxed, Relacy shits its pants.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Joseph Seigh@3:633/10 to All on Wed Oct 14 20:55:07 2026
    On 10/14/26 6:11 PM, Chris M. Thomasson wrote:
    On 10/14/2026 2:55 PM, Chris M. Thomasson wrote:
    Why does the C++ memory model seem to require async SMR loads to
    basically NEED std::memory_order_consume, which iirc gets folded into
    acquire. on the load side of SMR?


    Pure ISO C++ no longer gives you a way to express ?this load only needs dependency ordering, no full acquire barrier.?

    Data dependent loads aren't really part of any memory model AFAIK.
    In the older intel docs, this was in the performance section.
    It would cause a stall in the pipeline which you could use
    to execute some other instruction. Out of order processors
    may not have this problem so much anymore maybe.

    McKenney came up with this to avoid having to use some
    more expensive memory barrier.

    But you had to be aware that dependent loads only ordered
    subsequent loads that were dependent on that load.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Oct 14 20:19:29 2026
    On 10/14/2026 5:55 PM, Joseph Seigh wrote:
    On 10/14/26 6:11 PM, Chris M. Thomasson wrote:
    On 10/14/2026 2:55 PM, Chris M. Thomasson wrote:
    Why does the C++ memory model seem to require async SMR loads to
    basically NEED std::memory_order_consume, which iirc gets folded into
    acquire. on the load side of SMR?


    Pure ISO C++ no longer gives you a way to express ?this load only
    needs dependency ordering, no full acquire barrier.?

    Data dependent loads aren't really part of any memory model AFAIK.
    In the older intel docs, this was in the performance section.
    It would cause a stall in the pipeline which you could use
    to execute some other instruction.˙ Out of order processors
    may not have this problem so much anymore maybe.

    McKenney came up with this to avoid having to use some
    more expensive memory barrier.

    Almost has to be why!


    But you had to be aware that dependent loads only ordered
    subsequent loads that were dependent on that load.

    shit... Well, so, in std C++ memory model what relacy simulates, I still
    need a std::memory_order_consume, which gets expressed as a damn acquire anyway. I am having trouble making anything better wrt the SMR loop.
    This as relaxed as I can get SMR loads for now:
    _______________
    per_node*
    smr_load(
    unsigned long tidx
    ) {
    for (;;)
    {
    per_node* node0 = m_node.load(rl::mo_relaxed, $);

    if (! node0)
    {
    RL_ASSERT(0); // hould never happen in this test!
    m_threads[tidx].m_haz_0.store(nullptr, rl::mo_relaxed, $);
    break;
    }

    m_threads[tidx].m_haz_0.store(node0, rl::mo_relaxed, $);

    // actually, iirc, a single seq_cst right here should work?
    // well, this is an async test...

    per_node* node1 = m_node.load(rl::mo_consume, $);

    // uncomment below, Relacy goes berserker!
    //per_node* node1 = m_node.load(rl::mo_relaxed, $);
    if (node0 == node1)
    {
    return node0;
    }
    }

    return nullptr;
    }
    _______________

    Any weaker and Relacy simply does not like it. Humm... I need to dig in
    a little more. Thanks Joe.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)