• Performance of xchg reg,reg

    From anton@[email protected] (Anton Ertl) to comp.arch on Tue Oct 13 08:43:47 2026
    From Newsgroup: comp.arch

    Microbenchmarks (and this text in HTML form) on <http://www.complang.tuwien.ac.at/anton/xchg/>.

    In compilers, in particular in SSA destruction, or, more generally,
    register allocation, you sometimes have situations where you want to
    swap the contents of registers, e.g., when r1 contains a and r2
    contains b on one path, while r1 contains b and r2 contains a on the
    other path, and both paths join. This can be achieved with 3 mov
    instructions, but requires an extra register. The AMD64 instruction
    set contains the instruction xchg, which swaps the registers without
    extra register.

    More generally, there may be more than two registers whose values have
    to be moved in a cyclic way. This also requires an extra register and
    (for an n-register cycle) n+1 mov instructions if performed using mov instructions, or it can be achieved with n-1 xchg instructions.

    Mov instructions are supported very well in recent CPU cores, with the
    cores usually being able to perform as many independent (and often
    even dependent) moves as the register renamer accepts instructions
    (e.g., if the register renamer accepts 8 instructions per cycle, 8
    moves per cycle can be performed, usually even dependent moves).

    But how do xchg instructions perform? Should a register allocator use
    them where they are convenient, or prefer to use mov instructions and
    an extra register?

    <http://www.complang.tuwien.ac.at/anton/xchg/> contains
    microbenchmarks and this posting presents results for them on various
    cores from Intel and AMD. The first set of microbenchmarks perform 1G
    xchg instructions in a loop containing 28 xchg instructions (plus two instructions for the loop).

    One (independent) contains a sequence of 7 xchg instructions that are
    fully independent of each other, all accessing different registers,
    followed by the same sequence another three times. So the xchg
    instructions are as independent as possible with 14 registers
    involved.

    The other (dependent) contains a sequence of 14 xchg instructions
    where each subsequent instruction uses one register of the previous instruction, implementing a 15-register cycle. This sequence is
    followed by the reversal of this sequence, resulting in performing the 15-register cycle in the other direction.

    Here are the results in Gcycles on recent microarchitectures, i.e., a
    result of 0.25 means that the microarchitecture performs 4 xchg
    instructions per cycle. Smaller is better.

    indep dep core family CPU
    0.26 0.26 Zen5 AMD Ryzen AI Pro 350
    0.35 0.35 Zen4 AMD Ryzen 8700G
    0.35 0.35 Zen3 AMD Ryzen 5800X
    0.61 1.50 Lion Cove Intel P Core Ultra 225
    1.00 1.50 Golden Cove Intel P Core i3-1315U
    0.82 1.50 Rocket Lake Intel P Xeon E-2388G
    2.07 2.05 Skymont Intel E Core Ultra 225
    3.45 3.45 Gracemont Intel E Core i3-1315U

    Given the results of the dependent benchmark, it looks like the AMD
    processors perform xchg in the register renamer, consuming the
    resources of two ordinary instructions there (probably because two
    result registers are involved).

    On Intel microarchitectures, whether P-cores or E-cores, but
    especially the latter, xchg seems to have gotten little love.

    Let's see how this affects cyclic moves between registers. The
    following microbenchmarks perform cyclic moves through 2-5 registers (cyc2-cyc5) in three different ways:

    mem Store the first register to memory, then perform n-1 moves among
    registers, then load the memory location into the final register.
    reg Move the first register into a spare register, then perform n-1
    moves among the cycled registers, then move the spare register
    into the final register.
    xchg Use n-1 xchg instructions.

    The benchmark loop contains 12 cycles, and cycles involving
    non-overlapping sets of registers are benchmarked (6 sets for cyc2, 4
    for cyc3, 3 for cyc4, 2 for cyc5). At least three different memory
    locations are used for holding the value of the first register in
    memory, but the same register is used as the spare register. Here are
    the results (execution cycles per cyclic move (i.e., n+1 movs in case
    of reg, n-1 xchgs in case of xchg).

    cyc2 | cyc3 | cyc4 | cyc5 |core
    mem reg xchg|mem reg xchg|mem reg xchg|mem reg xchg|
    0.50 0.50 0.27|0.67 0.58 0.52|0.83 0.83 0.77|1.08 0.83 1.02|Zen5
    1.00 0.51 0.36|1.00 0.68 0.69|1.00 0.85 1.03|1.01 1.01 1.36|Zen4
    1.00 0.51 0.42|1.00 0.68 0.70|1.00 0.92 1.03|1.02 1.01 1.36|Zen3
    0.50 0.40 0.68|0.54 0.56 1.28|0.67 0.66 1.97|0.81 0.81 4.21|Lion Cove
    0.61 0.53 1.00|0.70 0.70 2.00|0.89 0.90 3.00|1.06 1.08 4.41|Golden Cove
    0.82 0.67 1.00|0.87 0.83 2.00|1.08 1.08 3.00|1.22 1.22 4.66|Rocket Lake
    1.00 0.40 1.45|0.65 0.73 4.14|0.65 0.65 7.35|0.78 0.86 9.44|Skymont
    0.67 0.67 3.08|0.83 0.83 6.73|1.03 1.03 10.63|1.23 1.23 13.77|Gracemont

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when you
    have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3 (for
    reg) are borderline cases, and for shorter cycles xchg is better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Wed Oct 14 00:23:59 2026
    From Newsgroup: comp.arch

    On Tue, 13 Oct 2026 08:43:47 GMT, Anton Ertl wrote:

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when
    you have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3
    (for reg) are borderline cases, and for shorter cycles xchg is
    better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    You’d think both companies would be running similar kinds of
    instruction workloads to find the things worth optimizing in their CPU architectures. But perhaps not ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Wed Oct 14 07:00:23 2026
    From Newsgroup: comp.arch

    Lawrence =?iso-8859-13?q?D=FFOliveiro?= <[email protected]d> writes:
    On Tue, 13 Oct 2026 08:43:47 GMT, Anton Ertl wrote:

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when
    you have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3
    (for reg) are borderline cases, and for shorter cycles xchg is
    better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    You’d think both companies would be running similar kinds of
    instruction workloads to find the things worth optimizing in their CPU >architectures. But perhaps not ...

    Or maybe, given the structure of the renamer, an AMD engineer saw a
    relatively easy way to implement xchg efficiently, and did it, without
    first looking at how often xchg occurs in benchmark programs. And at
    Intel, either no engineer thought about this, or the structure of the
    renamer makes an efficient implementation much harder.

    It makes me wonder, however, why cyc2xchg is more expensive than
    cyc2reg, though. An easy implementation should be to decode xchg reg,
    reg into three mov reg, reg (i.e., what cyc2reg implements), where the
    spare register is a non-architectural register. But on every measured
    Intel microarchitecture cyc2xchg is substantially slower than cyc2reg.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Wed Oct 14 22:29:14 2026
    From Newsgroup: comp.arch

    On Tue, 13 Oct 2026 08:43:47 GMT
    [email protected] (Anton Ertl) wrote:

    Microbenchmarks (and this text in HTML form) on <http://www.complang.tuwien.ac.at/anton/xchg/>.

    In compilers, in particular in SSA destruction, or, more generally,
    register allocation, you sometimes have situations where you want to
    swap the contents of registers, e.g., when r1 contains a and r2
    contains b on one path, while r1 contains b and r2 contains a on the
    other path, and both paths join. This can be achieved with 3 mov instructions, but requires an extra register. The AMD64 instruction
    set contains the instruction xchg, which swaps the registers without
    extra register.

    More generally, there may be more than two registers whose values have
    to be moved in a cyclic way. This also requires an extra register and
    (for an n-register cycle) n+1 mov instructions if performed using mov instructions, or it can be achieved with n-1 xchg instructions.

    Mov instructions are supported very well in recent CPU cores, with the
    cores usually being able to perform as many independent (and often
    even dependent) moves as the register renamer accepts instructions
    (e.g., if the register renamer accepts 8 instructions per cycle, 8
    moves per cycle can be performed, usually even dependent moves).

    But how do xchg instructions perform? Should a register allocator use
    them where they are convenient, or prefer to use mov instructions and
    an extra register?

    <http://www.complang.tuwien.ac.at/anton/xchg/> contains
    microbenchmarks and this posting presents results for them on various
    cores from Intel and AMD. The first set of microbenchmarks perform 1G
    xchg instructions in a loop containing 28 xchg instructions (plus two instructions for the loop).

    One (independent) contains a sequence of 7 xchg instructions that are
    fully independent of each other, all accessing different registers,
    followed by the same sequence another three times. So the xchg
    instructions are as independent as possible with 14 registers
    involved.

    The other (dependent) contains a sequence of 14 xchg instructions
    where each subsequent instruction uses one register of the previous instruction, implementing a 15-register cycle. This sequence is
    followed by the reversal of this sequence, resulting in performing the 15-register cycle in the other direction.

    Here are the results in Gcycles on recent microarchitectures, i.e., a
    result of 0.25 means that the microarchitecture performs 4 xchg
    instructions per cycle. Smaller is better.

    indep dep core family CPU
    0.26 0.26 Zen5 AMD Ryzen AI Pro 350
    0.35 0.35 Zen4 AMD Ryzen 8700G
    0.35 0.35 Zen3 AMD Ryzen 5800X
    0.61 1.50 Lion Cove Intel P Core Ultra 225
    1.00 1.50 Golden Cove Intel P Core i3-1315U
    0.82 1.50 Rocket Lake Intel P Xeon E-2388G
    2.07 2.05 Skymont Intel E Core Ultra 225
    3.45 3.45 Gracemont Intel E Core i3-1315U

    Given the results of the dependent benchmark, it looks like the AMD processors perform xchg in the register renamer, consuming the
    resources of two ordinary instructions there (probably because two
    result registers are involved).

    On Intel microarchitectures, whether P-cores or E-cores, but
    especially the latter, xchg seems to have gotten little love.

    Let's see how this affects cyclic moves between registers. The
    following microbenchmarks perform cyclic moves through 2-5 registers (cyc2-cyc5) in three different ways:

    mem Store the first register to memory, then perform n-1 moves among
    registers, then load the memory location into the final register.
    reg Move the first register into a spare register, then perform n-1
    moves among the cycled registers, then move the spare register
    into the final register.
    xchg Use n-1 xchg instructions.

    The benchmark loop contains 12 cycles, and cycles involving
    non-overlapping sets of registers are benchmarked (6 sets for cyc2, 4
    for cyc3, 3 for cyc4, 2 for cyc5). At least three different memory
    locations are used for holding the value of the first register in
    memory, but the same register is used as the spare register. Here are
    the results (execution cycles per cyclic move (i.e., n+1 movs in case
    of reg, n-1 xchgs in case of xchg).

    cyc2 | cyc3 | cyc4 | cyc5 |core
    mem reg xchg|mem reg xchg|mem reg xchg|mem reg xchg|
    0.50 0.50 0.27|0.67 0.58 0.52|0.83 0.83 0.77|1.08 0.83 1.02|Zen5
    1.00 0.51 0.36|1.00 0.68 0.69|1.00 0.85 1.03|1.01 1.01 1.36|Zen4
    1.00 0.51 0.42|1.00 0.68 0.70|1.00 0.92 1.03|1.02 1.01 1.36|Zen3
    0.50 0.40 0.68|0.54 0.56 1.28|0.67 0.66 1.97|0.81 0.81 4.21|Lion
    Cove 0.61 0.53 1.00|0.70 0.70 2.00|0.89 0.90 3.00|1.06 1.08
    4.41|Golden Cove 0.82 0.67 1.00|0.87 0.83 2.00|1.08 1.08 3.00|1.22
    1.22 4.66|Rocket Lake 1.00 0.40 1.45|0.65 0.73 4.14|0.65 0.65
    7.35|0.78 0.86 9.44|Skymont 0.67 0.67 3.08|0.83 0.83 6.73|1.03 1.03 10.63|1.23 1.23 13.77|Gracemont

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when you
    have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3 (for
    reg) are borderline cases, and for shorter cycles xchg is better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    - anton


    Interesting. Thank you.




    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Wed Oct 14 22:35:53 2026
    From Newsgroup: comp.arch


    [email protected] (Anton Ertl) posted:

    /ERROR "unexpected byte sequence starting at index 607: '\xE2'" while decoding/:

    Lawrence =?iso-8859-13?q?D=FFOliveiro?= <[email protected]d> writes:
    On Tue, 13 Oct 2026 08:43:47 GMT, Anton Ertl wrote:

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when
    you have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3
    (for reg) are borderline cases, and for shorter cycles xchg is
    better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    You’d think both companies would be running similar kinds of >instruction workloads to find the things worth optimizing in their CPU >architectures. But perhaps not ...

    Or maybe, given the structure of the renamer, an AMD engineer saw a relatively easy way to implement xchg efficiently, and did it, without
    first looking at how often xchg occurs in benchmark programs. And at
    Intel, either no engineer thought about this, or the structure of the
    renamer makes an efficient implementation much harder.

    Unlike Mainframes where sort is bread-and-butter operation, on PCs
    (and similar) it is not.

    It makes me wonder, however, why cyc2xchg is more expensive than
    cyc2reg, though. An easy implementation should be to decode xchg reg,
    reg into three mov reg, reg (i.e., what cyc2reg implements), where the
    spare register is a non-architectural register. But on every measured
    Intel microarchitecture cyc2xchg is substantially slower than cyc2reg.

    - anton
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Wed Oct 14 23:07:04 2026
    From Newsgroup: comp.arch

    On Wed, 14 Oct 2026 22:35:53 GMT, MitchAlsup wrote:

    Unlike Mainframes where sort is bread-and-butter operation, on PCs
    (and similar) it is not.

    You think Timsort might run faster on a mainframe than a PC?

    It was invented by one of the Python developers.

    <https://en.wikipedia.org/wiki/Timsort>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Thu Oct 15 06:05:34 2026
    From Newsgroup: comp.arch

    MitchAlsup <[email protected]d> writes:
    Unlike Mainframes where sort is bread-and-butter operation, on PCs
    (and similar) it is not.

    And the relevance of that for "Performance of xchg reg,reg" is?

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Thu Oct 15 07:06:53 2026
    From Newsgroup: comp.arch

    [email protected] (Anton Ertl) writes:
    MitchAlsup <[email protected]d> writes:
    Unlike Mainframes where sort is bread-and-butter operation, on PCs
    (and similar) it is not.

    And the relevance of that for "Performance of xchg reg,reg" is?

    To give you an idea what xchg reg,reg is good for:

    long foo(long a, long b);

    long bar(long a, long b)
    {
    return foo(b,a);
    }

    Both gcc-16 and clang-19 (even with -mtune=znver5) compile this to:

    0000000000000000 <bar>:
    0: 48 89 f8 mov %rdi,%rax
    3: 48 89 f7 mov %rsi,%rdi
    6: 48 89 c6 mov %rax,%rsi
    9: e9 00 00 00 00 jmp e <bar+0xe> #actually jmp foo

    This could be replaced with

    xchg %rdi,%rsi
    jmp foo


    It's less obvious for

    long foo(long a, long b);

    long bar(long a, long b, long c, long d)
    {
    return foo(b-c,a-d);
    }

    The gcc-12 (different machines) output even with -mtune=znver3 is:

    0000000000000000 <bar>:
    0: 48 89 f8 mov %rdi,%rax
    3: 48 29 d6 sub %rdx,%rsi
    6: 48 29 c8 sub %rcx,%rax
    9: 48 89 f7 mov %rsi,%rdi
    c: 48 89 c6 mov %rax,%rsi
    f: e9 00 00 00 00 jmp 14 <bar+0x14>

    and the clang-14 output is similar. This could be shortened to:

    sub %rdx,%rsi
    sub %rcx,%rdi
    xchg %rdi,%rsi
    jmp foo

    It also happens with control flow (that's what the SSA destruction on
    my web page refers to):

    long bar(long a, long b, long c, long d)
    {
    if (a<b) {
    long tmp=c;
    c=d-a;
    d=tmp-b;
    }
    return 2*c+d;
    }

    compiles (gcc-12 -O3 -mtune=znver3) to:

    0000000000000000 <bar>:
    0: 48 39 f7 cmp %rsi,%rdi
    3: 7d 0f jge 14 <bar+0x14>
    5: 48 89 c8 mov %rcx,%rax
    8: 48 29 f2 sub %rsi,%rdx
    b: 48 29 f8 sub %rdi,%rax
    e: 48 89 d1 mov %rdx,%rcx
    11: 48 89 c2 mov %rax,%rdx
    14: 48 8d 04 51 lea (%rcx,%rdx,2),%rax
    18: c3 ret

    and could be:

    cmp %rsi,%rdi
    jge L1
    sub %rsi,%rdx
    sub %rdi,%rcx
    xchg %rdx,%rcx
    L1: lea (%rcx,%rdx,2),%rax
    ret

    Given that most operations on AMD64 are performed with two-address
    (for binary operations) or one-address (for unary operations), the
    compiler can usually not use target preferencing to get data into the
    required registers with little or no extra move instructions. So the
    need to rearrange registers at some point is especially relevant on
    this architecture; and it has the xchg instruction to make the
    rearrangements shorter, and, on AMD processors, faster.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Thu Oct 15 14:21:07 2026
    From Newsgroup: comp.arch

    On 10/13/2026 1:43 AM, Anton Ertl wrote:
    Microbenchmarks (and this text in HTML form) on <http://www.complang.tuwien.ac.at/anton/xchg/>.

    In compilers, in particular in SSA destruction, or, more generally,
    register allocation, you sometimes have situations where you want to
    swap the contents of registers, e.g., when r1 contains a and r2
    contains b on one path, while r1 contains b and r2 contains a on the
    other path, and both paths join. This can be achieved with 3 mov instructions, but requires an extra register. The AMD64 instruction
    set contains the instruction xchg, which swaps the registers without
    extra register.

    More generally, there may be more than two registers whose values have
    to be moved in a cyclic way. This also requires an extra register and
    (for an n-register cycle) n+1 mov instructions if performed using mov instructions, or it can be achieved with n-1 xchg instructions.

    Mov instructions are supported very well in recent CPU cores, with the
    cores usually being able to perform as many independent (and often
    even dependent) moves as the register renamer accepts instructions
    (e.g., if the register renamer accepts 8 instructions per cycle, 8
    moves per cycle can be performed, usually even dependent moves).

    But how do xchg instructions perform? Should a register allocator use
    them where they are convenient, or prefer to use mov instructions and
    an extra register?

    <http://www.complang.tuwien.ac.at/anton/xchg/> contains
    microbenchmarks and this posting presents results for them on various
    cores from Intel and AMD. The first set of microbenchmarks perform 1G
    xchg instructions in a loop containing 28 xchg instructions (plus two instructions for the loop).

    One (independent) contains a sequence of 7 xchg instructions that are
    fully independent of each other, all accessing different registers,
    followed by the same sequence another three times. So the xchg
    instructions are as independent as possible with 14 registers
    involved.

    The other (dependent) contains a sequence of 14 xchg instructions
    where each subsequent instruction uses one register of the previous instruction, implementing a 15-register cycle. This sequence is
    followed by the reversal of this sequence, resulting in performing the 15-register cycle in the other direction.

    Here are the results in Gcycles on recent microarchitectures, i.e., a
    result of 0.25 means that the microarchitecture performs 4 xchg
    instructions per cycle. Smaller is better.

    indep dep core family CPU
    0.26 0.26 Zen5 AMD Ryzen AI Pro 350
    0.35 0.35 Zen4 AMD Ryzen 8700G
    0.35 0.35 Zen3 AMD Ryzen 5800X
    0.61 1.50 Lion Cove Intel P Core Ultra 225
    1.00 1.50 Golden Cove Intel P Core i3-1315U
    0.82 1.50 Rocket Lake Intel P Xeon E-2388G
    2.07 2.05 Skymont Intel E Core Ultra 225
    3.45 3.45 Gracemont Intel E Core i3-1315U

    Given the results of the dependent benchmark, it looks like the AMD processors perform xchg in the register renamer, consuming the
    resources of two ordinary instructions there (probably because two
    result registers are involved).

    On Intel microarchitectures, whether P-cores or E-cores, but
    especially the latter, xchg seems to have gotten little love.

    Let's see how this affects cyclic moves between registers. The
    following microbenchmarks perform cyclic moves through 2-5 registers (cyc2-cyc5) in three different ways:

    mem Store the first register to memory, then perform n-1 moves among
    registers, then load the memory location into the final register.
    reg Move the first register into a spare register, then perform n-1
    moves among the cycled registers, then move the spare register
    into the final register.
    xchg Use n-1 xchg instructions.

    The benchmark loop contains 12 cycles, and cycles involving
    non-overlapping sets of registers are benchmarked (6 sets for cyc2, 4
    for cyc3, 3 for cyc4, 2 for cyc5). At least three different memory
    locations are used for holding the value of the first register in
    memory, but the same register is used as the spare register. Here are
    the results (execution cycles per cyclic move (i.e., n+1 movs in case
    of reg, n-1 xchgs in case of xchg).

    cyc2 | cyc3 | cyc4 | cyc5 |core
    mem reg xchg|mem reg xchg|mem reg xchg|mem reg xchg|
    0.50 0.50 0.27|0.67 0.58 0.52|0.83 0.83 0.77|1.08 0.83 1.02|Zen5
    1.00 0.51 0.36|1.00 0.68 0.69|1.00 0.85 1.03|1.01 1.01 1.36|Zen4
    1.00 0.51 0.42|1.00 0.68 0.70|1.00 0.92 1.03|1.02 1.01 1.36|Zen3
    0.50 0.40 0.68|0.54 0.56 1.28|0.67 0.66 1.97|0.81 0.81 4.21|Lion Cove
    0.61 0.53 1.00|0.70 0.70 2.00|0.89 0.90 3.00|1.06 1.08 4.41|Golden Cove 0.82 0.67 1.00|0.87 0.83 2.00|1.08 1.08 3.00|1.22 1.22 4.66|Rocket Lake 1.00 0.40 1.45|0.65 0.73 4.14|0.65 0.65 7.35|0.78 0.86 9.44|Skymont
    0.67 0.67 3.08|0.83 0.83 6.73|1.03 1.03 10.63|1.23 1.23 13.77|Gracemont

    On Zen5, even a 5-register cycle can be profitably implemented with
    xchg when you have no spare register, a 4-register cycle even when you
    have a spare register. For Zen4 and Zen3 cyc4 (for mem) and cyc3 (for
    reg) are borderline cases, and for shorter cycles xchg is better.

    On Intel processors, xchg is so slow that it never is profitable to
    use it. The slowness takes on extreme values in the E-cores, with
    slowdowns by a factor >10 for cyc4 and cyc5.

    - anton

    Well, for some reason the LOCK prefix is implied for XCHG.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Thu Oct 15 21:42:35 2026
    From Newsgroup: comp.arch

    On Thu, 15 Oct 2026 14:21:07 -0700, Chris M. Thomasson wrote:

    Well, for some reason the LOCK prefix is implied for XCHG.

    I can imagine that being useful when accessing memory, but not just
    for exchanging registers ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 16 05:50:55 2026
    From Newsgroup: comp.arch

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based
    on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is |automatically implemented for the duration of the exchange operation, |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case, but asserting the
    LOCK# signal would make no difference, because: "the LOCK# signal
    ensures that the processor has exclusive use of any shared memory
    while the signal is asserted" and "the processor’s cache coherency
    mechanism ensures that the operation is carried out atomically with
    regards to memory", but "xchg reg, reg" does not use memory at all,
    and other processors have no access to a processor's registers.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Fri Oct 16 11:34:41 2026
    From Newsgroup: comp.arch

    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:
    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based
    on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking
    protocol is |automatically implemented for the duration of the
    exchange operation, |regardless of the presence or absence of the
    LOCK prefix or of the |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of
    the |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,
    No, it does not.
    but asserting the
    LOCK# signal would make no difference, because: "the LOCK# signal
    ensures that the processor has exclusive use of any shared memory
    while the signal is asserted" and "the processor’s cache coherency mechanism ensures that the operation is carried out atomically with
    regards to memory", but "xchg reg, reg" does not use memory at all,
    and other processors have no access to a processor's registers.

    - anton
    Intel text (325383-060US September 2016):
    Exchanges the contents of the destination (first) and source (second)
    operands. The operands can be two general- purpose registers or a
    register and a memory location. If a memory operand is referenced, the processor’s locking protocol is automatically implemented for the
    duration of the exchange operation, regardless of the presence or
    absence of the LOCK prefix or of the value of the IOPL. (See the LOCK
    prefix description in this chapter for more information on the locking protocol.) This instruction is useful for implementing semaphores or
    similar data structures for process synchronization. (See “Bus Locking”
    in Chapter 8 of the Intel® 64 and IA-32 Architectures Software
    Developer’s Manual, Volume 3A, for more information on bus locking.)
    The XCHG instruction can also be used instead of the BSWAP instruction
    for 16-bit operands. In 64-bit mode, the instruction’s default
    operation size is 32 bits. Using a REX prefix in the form of REX.R
    permits access to additional registers (R8-R15). Using a REX prefix in
    the form of REX.W promotes operation to 64 bits. See the summary chart
    at the beginning of this section for encoding data and limits.
    NOTE
    XCHG (E)AX, (E)AX (encoded instruction byte is 90H) is an alias for NOP regardless of data size prefixes, including REX.W.
    AMD Text (24594 Rev. 3.04 April 2003):
    Exchanges the contents of the two operands. The operands can be two
    general- purpose registers or a register and a memory location. If
    either operand references memory, the processor locks automatically,
    whether or not the LOCK prefix is used and independently of the value
    of IOPL. For details about the LOCK prefix, see “Lock Prefix” on page
    10. The x86 architecture commonly uses the XCHG EAX, EAX instruction
    (opcode 90h) as a one-byte NOP. In 64-bit mode, the processor treats
    opcode 90h as a true NOP only if it would exchange rAX with itself.
    Without this special handling, the instruction would zero-extend the
    upper 32 bits of RAX, and thus it would not be a true no- operation.
    Opcode 90h can still be used to exchange rAX and r8 if the appropriate
    REX prefix is used. This special handling does not apply to the
    two-byte ModRM form of the XCHG instruction.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Terje Mathisen@[email protected] to comp.arch on Fri Oct 16 14:45:56 2026
    From Newsgroup: comp.arch

    Lawrence D’Oliveiro wrote:
    On Thu, 15 Oct 2026 14:21:07 -0700, Chris M. Thomasson wrote:

    Well, for some reason the LOCK prefix is implied for XCHG.

    I can imagine that being useful when accessing memory, but not just
    for exchanging registers ...
    The implied LOCK only happens with a memory operand specified in the r/m byte. Terje
    --
    - <Terje.Mathisen at tmsw.no>
    "almost all programming can be viewed as an exercise in caching"
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From EricP@[email protected] to comp.arch on Fri Oct 16 09:47:39 2026
    From Newsgroup: comp.arch

    On 2026-Oct-15 03:06, Anton Ertl wrote:
    [email protected] (Anton Ertl) writes:
    MitchAlsup <[email protected]d> writes:
    Unlike Mainframes where sort is bread-and-butter operation, on PCs
    (and similar) it is not.

    And the relevance of that for "Performance of xchg reg,reg" is?

    To give you an idea what xchg reg,reg is good for:

    long foo(long a, long b);

    long bar(long a, long b)
    {
    return foo(b,a);
    }

    Both gcc-16 and clang-19 (even with -mtune=znver5) compile this to:

    0000000000000000 <bar>:
    0: 48 89 f8 mov %rdi,%rax
    3: 48 89 f7 mov %rsi,%rdi
    6: 48 89 c6 mov %rax,%rsi
    9: e9 00 00 00 00 jmp e <bar+0xe> #actually jmp foo

    This could be replaced with

    xchg %rdi,%rsi
    jmp foo

    There is also the xor swap which doesn't need an extra register

    xor rax,rbx
    xor rbx,rax
    xor rax,rbx



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Fri Oct 16 16:04:10 2026
    From Newsgroup: comp.arch

    EricP <[email protected]> writes:
    On 2026-Oct-15 03:06, Anton Ertl wrote:
    Both gcc-16 and clang-19 (even with -mtune=znver5) compile this to:

    0000000000000000 <bar>:
    0: 48 89 f8 mov %rdi,%rax
    3: 48 89 f7 mov %rsi,%rdi
    6: 48 89 c6 mov %rax,%rsi
    9: e9 00 00 00 00 jmp e <bar+0xe> #actually jmp foo

    This could be replaced with

    xchg %rdi,%rsi
    jmp foo

    There is also the xor swap which doesn't need an extra register

    xor rax,rbx
    xor rbx,rax
    xor rax,rbx

    That has a latency of 3 cycles and (probably less of a problem)
    consumes 3 ALU slots. Maybe Gracemont uses this internally, the
    number of cycles for the xchg variants of the cycN benchmarks would be compatible with that explanation. With 0-cycle store-to-load
    forwarding in recent processors, storing to memory and loading from
    memory is preferable on Intel processors if no spare register is
    available; and on AMD processors, xchg for cyc2 and cyc3, and
    sometimes on cyc4, cyc5. My guess is that using xor would lead to
    huge slowdowns, even compared to storing the value in memory.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Fri Oct 16 18:23:38 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based
    on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is
    |automatically implemented for the duration of the exchange operation,
    |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the
    |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,

    No, it does not.

    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    Personally, I suspect it's the one in the `XCHG` description.
    Context is important, and the full paragraph that talks about
    `XCHG` includes more:

    |The LOCK prefix can be prepended only to the following
    |instructions and only to those forms of the instructions where
    |the destination operand is a memory operand: `ADD`, `ADC`,
    |`AND`, `BTC`, `BTR`, `BTS`, `CMPXCHG`, `CMPXCH8B`,
    |`CMPXCHG16B`, `DEC`, `INC`, `NEG`, `NOT`, `OR`, `SBB`, `SUB`,
    |`XOR`, `XADD`, and `XCHG`. If the `LOCK` prefix is used with
    |one of these instructions and the source operand is a memory
    |operand, an undefined opcode exception (`#UD`) may be
    |generated. An undefined opcode exception will also be
    |generated if the `LOCK` prefix is used with any instruction not
    |in the above list. The `XCHG` instruction always asserts the
    |`LOCK#` signal regardless of the presence or absence of the
    |`LOCK` prefix.

    So while the last sentence seems independent of operands, its
    presence in this paragraph leads me to believe that it only
    applies in the context of a destination operand that is a
    memory operand.

    If not, however, an interesting question is, does an `XCHG` that
    only specifies register operands affect memory ordering?
    Looking at secs 11.1 and 11.2, I believe the answer is no: the
    description of locked instructions explicitly only applies to
    those with memory operands.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Thomas Koenig@[email protected] to comp.arch on Fri Oct 16 20:38:22 2026
    From Newsgroup: comp.arch

    Dan Cross <[email protected]> schrieb:
    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based
    on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is
    |automatically implemented for the duration of the exchange operation,
    |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the
    |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,

    No, it does not.

    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.
    --
    This USENET posting was made without artificial intelligence,
    artificial impertinence, artificial arrogance, artificial stupidity,
    artificial flavorings or artificial colorants.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.arch on Fri Oct 16 20:48:12 2026
    From Newsgroup: comp.arch

    Thomas Koenig <[email protected]> writes:
    Dan Cross <[email protected]> schrieb:
    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based
    on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is
    |automatically implemented for the duration of the exchange operation, >>>> |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the >>>> |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,

    No, it does not.

    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Did you mean 'without memory operands'? It's clear that there
    is no need to acquire the cache and/or system lock if there
    are no memory operands, and a substantial performance penalty;
    besides, which cache line would it use for the case where both
    operands are registers?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Fri Oct 16 14:28:35 2026
    From Newsgroup: comp.arch

    On 10/16/2026 1:48 PM, Scott Lurndal wrote:
    Thomas Koenig <[email protected]> writes:
    Dan Cross <[email protected]> schrieb:
    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based >>>>> on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is
    |automatically implemented for the duration of the exchange operation, >>>>> |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the >>>>> |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,

    No, it does not.

    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Did you mean 'without memory operands'? It's clear that there
    is no need to acquire the cache and/or system lock if there
    are no memory operands, and a substantial performance penalty;
    besides, which cache line would it use for the case where both
    operands are registers?

    One on the threads stack? Kidding, but I have seen people use LOCK XCHG
    for memory operands, and XCHG for "local" registers and such. But, the
    Intel docs are rather interesting. Using XCHG works, without LOCK
    prefix. But, its a point of confusion.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sat Oct 17 02:50:31 2026
    From Newsgroup: comp.arch

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why? I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Sat Oct 17 05:46:32 2026
    From Newsgroup: comp.arch

    On Fri, 16 Oct 2026 09:47:39 -0400, EricP wrote:

    There is also the xor swap which doesn't need an extra register

    xor rax,rbx
    xor rbx,rax
    xor rax,rbx

    It's a clever trick from the old days, but not really
    performance-oriented ...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Thomas Koenig@[email protected] to comp.arch on Sat Oct 17 09:48:13 2026
    From Newsgroup: comp.arch

    Scott Lurndal <[email protected]> schrieb:
    Thomas Koenig <[email protected]> writes:
    Dan Cross <[email protected]> schrieb:
    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Fri, 16 Oct 2026 05:50:55 GMT
    [email protected] (Anton Ertl) wrote:

    "Chris M. Thomasson" <[email protected]> writes:
    Well, for some reason the LOCK prefix is implied for XCHG.

    According to <https://www.felixcloutier.com/x86/xchg> (which is based >>>>> on (I think) Intel's documentation):

    |If a memory operand is referenced, the processor’s locking protocol is
    |automatically implemented for the duration of the exchange operation, >>>>> |regardless of the presence or absence of the LOCK prefix or of the
    |value of the IOPL.

    This does not cover the "xchg reg, reg" case.

    <https://www.felixcloutier.com/x86/lock> says:
    |The XCHG instruction always asserts the LOCK# signal regardless of the >>>>> |presence or absence of the LOCK prefix.

    This seems to include the "xchg reg, reg" case,

    No, it does not.

    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Did you mean 'without memory operands'?

    Yes. I canceled the article, but either was too late or some
    server does not honor the cancel.

    It's clear that there
    is no need to acquire the cache and/or system lock if there
    are no memory operands, and a substantial performance penalty;
    besides, which cache line would it use for the case where both
    operands are registers?

    Exactly.
    --
    This USENET posting was made without artificial intelligence,
    artificial impertinence, artificial arrogance, artificial stupidity,
    artificial flavorings or artificial colorants.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sat Oct 17 17:11:16 2026
    From Newsgroup: comp.arch

    [email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sat Oct 17 17:31:15 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote: >[email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    No, I get that; I mean in the case where both operands to `XCHG`
    are _register_ operands.

    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    But as I said, I don't think that is what the sentence in
    question is _actually_ saying, and I really don't think that
    `xchg %ecx, %eax` _actually_ asserts `LOCK#` (or, these days,
    has anything to do with cache coherency and memory ordering).

    I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sat Oct 17 19:39:42 2026
    From Newsgroup: comp.arch

    [email protected] (Dan Cross) posted:

    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote: >[email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    No, I get that; I mean in the case where both operands to `XCHG`
    are _register_ operands.

    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard. It took
    me nearly 40 years of doing so to get to the point a mischievous
    engineer could NOT misunderstand what I had written. It is harder
    wo write high quality documentation than perform circuit design.

    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    But as I said, I don't think that is what the sentence in
    question is _actually_ saying, and I really don't think that
    `xchg %ecx, %eax` _actually_ asserts `LOCK#` (or, these days,
    has anything to do with cache coherency and memory ordering).

    I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Sat Oct 17 23:20:02 2026
    From Newsgroup: comp.arch

    On Sat, 17 Oct 2026 19:39:42 GMT
    MitchAlsup <[email protected]d> wrote:

    [email protected] (Dan Cross) posted:

    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote: >[email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the
    text Anton quoted, while the description of `XCHG` itself
    makes clear that the destination operand must be a memory
    operand for the locking protocol to automatically apply.
    Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    No, I get that; I mean in the case where both operands to `XCHG`
    are _register_ operands.

    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard. It took
    me nearly 40 years of doing so to get to the point a mischievous
    engineer could NOT misunderstand what I had written.

    How do you know?
    Nature is inventive.

    It is harder
    wo write high quality documentation than perform circuit design.

    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    But as I said, I don't think that is what the sentence in
    question is _actually_ saying, and I really don't think that
    `xchg %ecx, %eax` _actually_ asserts `LOCK#` (or, these days,
    has anything to do with cache coherency and memory ordering).

    I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Sat Oct 17 20:54:44 2026
    From Newsgroup: comp.arch

    On Sat, 17 Oct 2026 19:39:42 GMT, MitchAlsup wrote:

    Writing high quality documentation is fundamentally hard.

    Isn’t that why formal specification languages were invented? For some
    reason they never caught on.

    For a classic example, look at the Algol-68 language spec. Yet many
    people threw up their hands in horror at how it was written.

    It took me nearly 40 years of doing so to get to the point a
    mischievous engineer could NOT misunderstand what I had written.

    Presumably you include lots of examples? I remember something Jerry
    Pournelle said, critiquing the product documentation he had to read
    for his columns in “BYTE” magazine, back in the day: “You can never
    have too many examples”.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From George Neuner@[email protected] to comp.arch on Sun Oct 18 08:59:00 2026
    From Newsgroup: comp.arch

    On Sat, 17 Oct 2026 19:39:42 GMT, MitchAlsup
    <[email protected]d> wrote:


    Writing high quality documentation is fundamentally hard. It took
    me nearly 40 years of doing so to get to the point a mischievous
    engineer could NOT misunderstand what I had written. It is harder
    wo write high quality documentation than perform circuit design.

    +1


    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    Also remember that the documents are describing the operations of a
    family of implementations. However unlikely, there may be members
    that still have to play by those old rules.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From George Neuner@[email protected] to comp.arch on Sun Oct 18 09:45:00 2026
    From Newsgroup: comp.arch

    On Sat, 17 Oct 2026 20:54:44 -0000 (UTC), Lawrence D´Oliveiro
    <[email protected]d> wrote:

    On Sat, 17 Oct 2026 19:39:42 GMT, MitchAlsup wrote:

    Writing high quality documentation is fundamentally hard.

    Isn’t that why formal specification languages were invented? For some >reason they never caught on.

    For a classic example, look at the Algol-68 language spec. Yet many
    people threw up their hands in horror at how it was written.

    The problem with the original report was that they attempted with the
    grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    Note that the *revised* report used a different grammar - something
    they called "NEST": still 2-level, still very complex [though less so
    than the original vW grammar], but they did not try to encode
    semantics directly, instead referencing discussions in accompanying
    text.

    I read both 68 reports - original and revised. Mind you it was long
    ago, but my recollection is that the revised report really wasn't any
    more understandable than the original ... just longer because the NEST formalism was somewhat less expressive than the vW.

    YMMV.


    It took me nearly 40 years of doing so to get to the point a
    mischievous engineer could NOT misunderstand what I had written.

    Presumably you include lots of examples? I remember something Jerry
    Pournelle said, critiquing the product documentation he had to read
    for his columns in “BYTE” magazine, back in the day: “You can never >have too many examples”.

    +1
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Sun Oct 18 14:08:34 2026
    From Newsgroup: comp.arch

    George Neuner <[email protected]> writes:
    On Sat, 17 Oct 2026 20:54:44 -0000 (UTC), Lawrence D´Oliveiro ><[email protected]d> wrote:
    Isn’t that why formal specification languages were invented? For some >>reason they never caught on.

    For a classic example, look at the Algol-68 language spec. Yet many
    people threw up their hands in horror at how it was written.

    The problem with the original report was that they attempted with the
    grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    My take is that BNF was a big success in formalizing a part of a
    language. So what do you do when you are successful? You try to
    follow up on that. So they wanted to formalize more of the language,
    and go beyond the limits of BNF (context-free grammars) with Vw
    grammars. This was technically successful, but from a usability POV
    it was not.

    Nevertheless, there have been attempts to formally specify programming languages completely, or at least more of them than just the
    context-free grammar part of them. AFAIK all attempts to formally
    specify everything in the language definition have been unsuccessful:
    not only did the specification become too hard to understand for the programmers, but it seems to me that the programming language also
    became to hard to extend by its designers.

    A team at the IBM Lab in Vienna made a formal specification for PL/I;
    I attended a lecture by Heinz Zemanek (the team leader) where he
    mentioned something about an implementor disagreeing with the formal specification for recursion (disagreements between implementor and specification can also happen with specifications written in a natural language, so that may not say much). Anyway, <https://en.wikipedia.org/wiki/PL/I#Standardization> says "The
    standard is couched as a formal definition[17] using a "PL/I
    Machine"[21] to specify the semantics." This sounds like the
    operational semantics that was developed by the IBM Lab Vienna, so
    maybe the standardization committee picked up this work. But it seems
    that the first standard never had a followon; was the definition too
    unwieldy?

    Standard ML has been formally specified, and, given the audience of
    this language, if any programming language may have success going
    there, it should be a language like ML. There is a first revision
    (1990) and a second revision (1997), and SML seems to have reached the
    end of its evolution there.

    Other programming languages have formalized parts of the language
    beyond the context-free grammar, probably the parts that can be
    described well with a formalism, such as the type system. I guess
    some of these attempts have been successful, and others not so much.

    Concerning terms like "semantic errors" or "static semantics" they
    make it appear that there is a fundamental difference between syntax
    and "static semantics" (the part that is not context-free and that is
    checked by the compiler). It seems to me that that's just a matter of
    what is expressed in the BNF. E.g., in Algol 60 the computation of
    conditions for if-statements have special BNF rules, whereas some
    later programming languages have a boolean type and putting a
    non-boolean between IF and THEN produces a type error, not a syntax
    error.

    So I don't think that there is a fundamental difference, and if there
    was a formalism that is as easy to work with (both for programmers and
    for language designers) as BNF is, we would be using that formalism
    for that; and if that formalism also took over the role that BNF has
    now, we would be considering all the errors that this formalism finds
    to be in the same category.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Sun Oct 18 15:08:23 2026
    From Newsgroup: comp.arch

    MitchAlsup <[email protected]d> writes: >[email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to deal
    with all kinds of red tape for such a fix, so unless there is good
    reason, you don't do it.

    This sentence already exists in my 1994-vintage Pentium Processor
    User's Manual Vol. 3. There it is preceeded by:

    |The LOCK prefix functions only with the following instructions:
    |
    |...
    |XCHG reg, mem
    |XCHG mem, reg
    |...

    With no occurence of XCHG reg, reg anywhere. But, OTOH, this is not
    really a contradiction to the sentence "The XCHG instruction always
    asserts the LOCK# signal regardless of the presence or absence of the
    LOCK prefix."

    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    Actually <https://www.felixcloutier.com/x86/lock> then says that
    "Beginning with the P6 family processors, when [...], the LOCK# signal
    is generally not asserted [...]" and still explains mechanism, finally
    saying "the operation is carried out atomically with regards to
    memory." If they wrote that as the description of the LOCK prefix,
    much of the rest could be deleted.

    Generally, an architecture manual should talk about architectural
    effects, not about asserted signals.

    The operational semantics given in
    <https://www.felixcloutier.com/x86/lock> is:

    | AssertLOCK#(DurationOfAccompaningInstruction);

    Oh boy.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Sun Oct 18 18:43:18 2026
    From Newsgroup: comp.arch

    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:
    MitchAlsup <[email protected]d> writes: >[email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to deal
    with all kinds of red tape for such a fix, so unless there is good
    reason, you don't do it.

    Frankly, I don't understand what both you and Dan Cross are talking
    about.
    I don't see how sentence from Intel's manual ("If a memory operand is referenced, the processor’s locking protocol is automatically
    implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the IOPL")
    or sentence from AMD's manual ("If either operand references memory,
    the processor locks automatically, whether or not the LOCK prefix is
    used and independently of the value of IOPL.") can be pssibly
    misunderstood.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From EricP@[email protected] to comp.arch on Sun Oct 18 12:31:13 2026
    From Newsgroup: comp.arch

    On 2026-Oct-17 13:31, Dan Cross wrote:
    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote:
    [email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    No, I get that; I mean in the case where both operands to `XCHG`
    are _register_ operands.

    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    But as I said, I don't think that is what the sentence in
    question is _actually_ saying, and I really don't think that
    `xchg %ecx, %eax` _actually_ asserts `LOCK#` (or, these days,
    has anything to do with cache coherency and memory ordering).

    I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.


    Intel Volume 3 System Programmers guide 10.1.2 Bus Locking
    10.1.2.1 Automatic Locking is explicit: the automatic locking for XCHG
    applies to memory operands only. There are a bunch of other situations
    where automatic locking is asserted, such as setting the Accessed and
    Modified bit on PTE's. BUT it can also depend on PTE caching attributes
    and cpu model number.

    The other manuals probably didn't want to worry programmers pretty little heads with all those grotty details.

    e.g.
    10.1.4 Effects of a LOCK Operation on Internal Processor Caches

    For the Intel486 and Pentium processors, the LOCK# signal is always asserted
    on the bus during a LOCK operation, even if the area of memory being locked
    is cached in the processor.

    For the P6 and more recent processor families, if the area of memory being locked during a LOCK operation is cached in the processor that is performing the LOCK operation as write-back memory and is completely contained in a
    cache line, the processor may not assert the LOCK# signal on the bus.
    ... blah blah blah



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 17:09:19 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote: >[email protected] (Dan Cross) posted:

    In article <[email protected]>,
    MitchAlsup <[email protected]d> wrote:
    [email protected] (Dan Cross) posted:

    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why?

    Older machines performed the read, returned the read data to
    a core and then sent the data to be written back to memory;
    where the time between the read and the write was unknowable.

    Some newer machines take the data to be written and package it
    up in an interconnect transaction so the read and write happen
    on back-to-back cycles with no possibility of interference.
    These are ATOMIC even without any bus-locking. The data read
    out is returned to the core.

    No, I get that; I mean in the case where both operands to `XCHG`
    are _register_ operands.

    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard. It took
    me nearly 40 years of doing so to get to the point a mischievous
    engineer could NOT misunderstand what I had written. It is harder
    wo write high quality documentation than perform circuit design.

    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    Maybe? Probably? I don't know. *shrug*

    I'm not trying to impugn the tech writers at Intel, who I think
    generally do a great job. But this particular paragraph has
    obviously lead to some confusion.

    Again, I think that, at the end of the day, `xchg reg, reg` has
    no effect on memory ordering at all, and that sentence is meant
    to be read within the context of that paragraph; ie, the `LOCK`
    prefix is implied if it's not specifically given _and_ the
    destination is a memory operand.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Sun Oct 18 16:57:26 2026
    From Newsgroup: comp.arch

    Michael S <[email protected]> writes:
    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:
    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG
    instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.
    ...
    Frankly, I don't understand what both you and Dan Cross are talking
    about.
    I don't see how sentence from Intel's manual ("If a memory operand is >referenced, the processor=E2=80=99s locking protocol is automatically >implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the IOPL")
    or sentence from AMD's manual ("If either operand references memory,
    the processor locks automatically, whether or not the LOCK prefix is
    used and independently of the value of IOPL.") can be pssibly
    misunderstood.

    Chris M. Thomasson wrote in <11arg45$2p70p$[email protected]>:
    |Well, for some reason the LOCK prefix is implied for XCHG.

    Given that the thread up to that point was aboyt XCHG reg, reg (and
    according to the subject it still is), he seems to be an example that
    what Intel wrote about XCHG and LOCK can be misunderstood. I looked
    at the documentation and cited the relevant sentences in <[email protected]>; most occurences clearly
    refer only to XCHG where one operand is in memory. The exception is:

    |The XCHG instruction always asserts the LOCK# signal regardless of the |presence or absence of the LOCK prefix.

    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg. I don't think that's
    what Intel intends and implements, but that's what a reading of their
    manual implies.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 17:40:00 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:

    MitchAlsup <[email protected]d> writes:
    [email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG
    instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to deal
    with all kinds of red tape for such a fix, so unless there is good
    reason, you don't do it.

    Frankly, I don't understand what both you and Dan Cross are talking
    about.

    Because you are not reading the same thing we are.

    I don't see how sentence from Intel's manual ("If a memory operand is >referenced, the processor’s locking protocol is automatically
    implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the IOPL")
    or sentence from AMD's manual ("If either operand references memory,
    the processor locks automatically, whether or not the LOCK prefix is
    used and independently of the value of IOPL.") can be pssibly
    misunderstood.

    Which part of the Intel and AMD manuals?

    What Anton raised, and what I'm also referring to, is a a single
    sentence in the SDM's description of the `LOCK` prefix. For
    reference, I am looking at Volume 2A, order number 253666-093US,
    published Sept 2026, page 3-565.

    Tucked away in the "Description" section, at the end the third
    paragraph, which describes what instructions can be prefaced by
    `LOCK` and under what conditions, is the single sentence that
    reads: "The `XCHG` instruction always asserts the `LOCK#` signal
    regardless of the presence or absence of the `LOCK` prefix."
    Note: that is a direct quote from the reference.

    We know that `XCHG` with a memory destination operand is atomic
    and affects memory ordering, etc, regardless of whether the
    `LOCK` prefix is explicitly given or not. The issue is that
    that sentence, taken in complete isolation, makes it sound like
    this is _also_ the case for `xchg reg, reg`, where the
    destination is a _register_ operand.

    I claim that that is a misreading, and that a reader should
    interpret that last sentence in the context of the first
    sentence in that paragraph, that refers specifically to memory
    operands; furthermore, other parts of the SDM are clear that
    `xchg reg, reg` has no impact on memory ordering, bus locks,
    etc.

    Regardless, that sentence is ambiguous. References to the
    description of `XCHG`, or to the locking protocols in volume 3,
    does not change that.

    The latest version of the entire Intel SDM is available online: https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
    I had already quoted the paragarph in question in its entirely.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Sun Oct 18 20:47:38 2026
    From Newsgroup: comp.arch

    On Sun, 18 Oct 2026 16:57:26 GMT
    [email protected] (Anton Ertl) wrote:

    Michael S <[email protected]> writes:
    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:
    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG
    instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.
    ...
    Frankly, I don't understand what both you and Dan Cross are talking
    about.
    I don't see how sentence from Intel's manual ("If a memory operand is >referenced, the processor=E2=80=99s locking protocol is automatically >implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the
    IOPL") or sentence from AMD's manual ("If either operand references
    memory, the processor locks automatically, whether or not the LOCK
    prefix is used and independently of the value of IOPL.") can be
    pssibly misunderstood.

    Chris M. Thomasson wrote in <11arg45$2p70p$[email protected]>:
    |Well, for some reason the LOCK prefix is implied for XCHG.

    Given that the thread up to that point was aboyt XCHG reg, reg (and
    according to the subject it still is), he seems to be an example that
    what Intel wrote about XCHG and LOCK can be misunderstood. I looked
    at the documentation and cited the relevant sentences in <[email protected]>; most occurences clearly
    refer only to XCHG where one operand is in memory. The exception is:

    |The XCHG instruction always asserts the LOCK# signal regardless of
    the |presence or absence of the LOCK prefix.


    What is a source of this? Intel, AMD or somebody else?

    And actually all the stuff about XCHG with memory operands does not contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg. I don't think that's
    what Intel intends and implements, but that's what a reading of their
    manual implies.

    - anton

    Somehow, it does not imply it to me.



    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 17:47:51 2026
    From Newsgroup: comp.arch

    In article <nv6BS.146451$[email protected]>,
    EricP <[email protected]> wrote:
    On 2026-Oct-17 13:31, Dan Cross wrote:
    [snip]
    Intel Volume 3 System Programmers guide 10.1.2 Bus Locking
    10.1.2.1 Automatic Locking is explicit:...
    [snip]

    Yes, which in my view, lends more support to requiring that the
    sentence in question in the description of the `LOCK` prefix be
    read in the context of the overall paragraph, which is clearly
    talking about cases where the destination is a memory operand.

    Sadly, however, that doesn't make the sentence itself any less
    ambiguous, and once you have ambiguity in a technical document
    like the SDM, you've got a problem.

    Intel can fix this easily by adding another phrase to that last
    sentence, ", when the destination is a memory operand." (Or
    words to that effect.) I'm speculating, but they probably
    haven't because it seems rather obvious that that is the intent,
    and no one has brought it up as a problem.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sun Oct 18 17:48:35 2026
    From Newsgroup: comp.arch

    Lawrence =?iso-8859-13?q?D=FFOliveiro?= <[email protected]d> posted:

    On Sat, 17 Oct 2026 19:39:42 GMT, MitchAlsup wrote:

    Writing high quality documentation is fundamentally hard.

    Isn’t that why formal specification languages were invented? For some reason they never caught on.

    There numerous examples of "minutia" in CPU design where one can
    never provide a sufficiently formal quantification of what that
    part does. A series of unsigned operations culminating in a signed
    operation that result in a single multi-wide signed result.

    For a classic example, look at the Algol-68 language spec. Yet many
    people threw up their hands in horror at how it was written.

    It took me nearly 40 years of doing so to get to the point a
    mischievous engineer could NOT misunderstand what I had written.

    Presumably you include lots of examples?

    Yes, a while back I was having a bit of trouble describing shift
    instructions {both signed and unsigned} in snippets of C-like
    code. Eventually, I drew up figures illustrating how each bit
    moved through the calculation(s). And the figures did way more
    in the definition department than any c-code snippet could.

    For example (especially) the double wide shift instructions and
    insert instructions that arise when the shift instruction is in
    the shadow of a CARRY modifier. It is easy in a figure to illus-
    trate how bits cross from one 64-bit container to another, over-
    flow off the top and shift up into another from the bottom (and
    vice versa).

    I remember something Jerry
    Pournelle said, critiquing the product documentation he had to read
    for his columns in “BYTE” magazine, back in the day: “You can never have too many examples”.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Sun Oct 18 20:54:30 2026
    From Newsgroup: comp.arch

    On Sun, 18 Oct 2026 17:40:00 -0000 (UTC)
    [email protected] (Dan Cross) wrote:
    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:

    MitchAlsup <[email protected]d> writes:
    [email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG
    instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to
    deal with all kinds of red tape for such a fix, so unless there is
    good reason, you don't do it.

    Frankly, I don't understand what both you and Dan Cross are talking
    about.

    Because you are not reading the same thing we are.

    I don't see how sentence from Intel's manual ("If a memory operand is >referenced, the processor’s locking protocol is automatically >implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the
    IOPL") or sentence from AMD's manual ("If either operand references
    memory, the processor locks automatically, whether or not the LOCK
    prefix is used and independently of the value of IOPL.") can be
    pssibly misunderstood.

    Which part of the Intel and AMD manuals?

    What Anton raised, and what I'm also referring to, is a a single
    sentence in the SDM's description of the `LOCK` prefix. For
    reference, I am looking at Volume 2A, order number 253666-093US,
    published Sept 2026, page 3-565.

    Tucked away in the "Description" section, at the end the third
    paragraph, which describes what instructions can be prefaced by
    `LOCK` and under what conditions, is the single sentence that
    reads: "The `XCHG` instruction always asserts the `LOCK#` signal
    regardless of the presence or absence of the `LOCK` prefix."
    Note: that is a direct quote from the reference.

    We know that `XCHG` with a memory destination operand is atomic
    and affects memory ordering, etc, regardless of whether the
    `LOCK` prefix is explicitly given or not. The issue is that
    that sentence, taken in complete isolation, makes it sound like
    this is _also_ the case for `xchg reg, reg`, where the
    destination is a _register_ operand.

    I claim that that is a misreading, and that a reader should
    interpret that last sentence in the context of the first
    sentence in that paragraph, that refers specifically to memory
    operands; furthermore, other parts of the SDM are clear that
    `xchg reg, reg` has no impact on memory ordering, bus locks,
    etc.

    Regardless, that sentence is ambiguous. References to the
    description of `XCHG`, or to the locking protocols in volume 3,
    does not change that.

    The latest version of the entire Intel SDM is available online: https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
    I had already quoted the paragarph in question in its entirely.

    - Dan C.

    When I want to know what particular insruction does I go to respective
    section in Instruction Set Reference.
    I can believe that there exist other methodes, but I prefere mine.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 17:59:43 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Anton Ertl <[email protected]> wrote:
    MitchAlsup <[email protected]d> writes: >>[email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG >instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to deal
    with all kinds of red tape for such a fix, so unless there is good
    reason, you don't do it.

    Nah; the SDM changes all the time. It's hard to hand out
    citations to it without an explicit version because of that.
    There are mistakes all over it; most of them are pretty minor,
    like cross-referring to an old section number or something.
    Each revision fixes a few and adds a few others.

    I think it just hasn't occurred to anyone that it could be
    clearer.

    This sentence already exists in my 1994-vintage Pentium Processor
    User's Manual Vol. 3. There it is preceeded by:

    |The LOCK prefix functions only with the following instructions:
    |
    |...
    |XCHG reg, mem
    |XCHG mem, reg
    |...

    With no occurence of XCHG reg, reg anywhere. But, OTOH, this is not
    really a contradiction to the sentence "The XCHG instruction always
    asserts the LOCK# signal regardless of the presence or absence of the
    LOCK prefix."

    Right. The current text says more or less the same thing,
    though phrased slightly differently: "The LOCK prefix can be
    prepended only to the following instructions and only to those
    forms of the instructions where the destination operand is a
    memory operand: [list of instructions...]."

    What they wrote may have well been exactly what the HW did back then
    but somewhere between then and now architects and designers figured
    out other ways and nobody went back to fully scrub the documents.

    Actually <https://www.felixcloutier.com/x86/lock> then says that
    "Beginning with the P6 family processors, when [...], the LOCK# signal
    is generally not asserted [...]" and still explains mechanism, finally
    saying "the operation is carried out atomically with regards to
    memory." If they wrote that as the description of the LOCK prefix,
    much of the rest could be deleted.

    Generally, an architecture manual should talk about architectural
    effects, not about asserted signals.

    The operational semantics given in
    <https://www.felixcloutier.com/x86/lock> is:

    | AssertLOCK#(DurationOfAccompaningInstruction);

    Oh boy.

    That part is fine. It's talking about the _explicit_ presence
    of a `LOCK` prefix, and given the constraints on the
    'accompaning' [sic] instruction, that tracks exactly what the
    description says. Volume 3A, sec 11.1.2, describes bus locking,
    and what "asserting LOCK#" means.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Sun Oct 18 18:01:18 2026
    From Newsgroup: comp.arch

    Michael S <[email protected]> posted:

    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:

    MitchAlsup <[email protected]d> writes: >[email protected] (Dan Cross) posted:
    What I'm saying is that, as written, the bits in the `LOCK`
    description above _could_ be interpreted to mean that _any_
    `XCHG` will always assert the `LOCK#` signal, including an
    `XCHG` that does not touch memory at all. The "Why?" was
    rhetorical, as in, "Why would the system do that?" For example,
    if one wrote, `xchg %ecx, %eax`, why should that assert `LOCK#`?
    Truly I don't know, and I was just speculating.

    Writing high quality documentation is fundamentally hard.

    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.

    My guess is that it is easy to fix in principle, but you have to deal
    with all kinds of red tape for such a fix, so unless there is good
    reason, you don't do it.


    Frankly, I don't understand what both you and Dan Cross are talking
    about.
    I don't see how sentence from Intel's manual ("If a memory operand is referenced, the processor’s locking protocol is automatically
    implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the IOPL")
    or sentence from AMD's manual ("If either operand references memory,
    the processor locks automatically, whether or not the LOCK prefix is
    used and independently of the value of IOPL.") can be pssibly
    misunderstood.

    Look at it from the perspective of the guy verifying that on-die
    interconnect is being used correctly by the cores. {{not every
    designer is inside the core !!}}

    Say protocol has space for XCHG-Lock and XCHG-without, and the cores
    are using later instead of former because the destination does not
    need the -lock part to be ATOMIC.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 18:07:27 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    On Sun, 18 Oct 2026 16:57:26 GMT
    [email protected] (Anton Ertl) wrote:

    Michael S <[email protected]> writes:
    On Sun, 18 Oct 2026 15:08:23 GMT
    [email protected] (Anton Ertl) wrote:
    I don't think that's the issue here. They just did not limit the
    sentence "The XCHG instruction always asserts the LOCK# signal
    regardless of the presence or absence of the LOCK prefix." to XCHG
    instructions with memory operands. That would be easy to fix, but
    they did not. And Chris M. Thomasson understood it as including
    XCHG reg, reg.
    ...
    Frankly, I don't understand what both you and Dan Cross are talking
    about.
    I don't see how sentence from Intel's manual ("If a memory operand is
    referenced, the processor=E2=80=99s locking protocol is automatically
    implemented for the duration of the exchange operation, regardless of
    the presence or absence of the LOCK prefix or of the value of the
    IOPL") or sentence from AMD's manual ("If either operand references
    memory, the processor locks automatically, whether or not the LOCK
    prefix is used and independently of the value of IOPL.") can be
    pssibly misunderstood.

    Chris M. Thomasson wrote in <11arg45$2p70p$[email protected]>:
    |Well, for some reason the LOCK prefix is implied for XCHG.

    Given that the thread up to that point was aboyt XCHG reg, reg (and
    according to the subject it still is), he seems to be an example that
    what Intel wrote about XCHG and LOCK can be misunderstood. I looked
    at the documentation and cited the relevant sentences in
    <[email protected]>; most occurences clearly
    refer only to XCHG where one operand is in memory. The exception is:

    |The XCHG instruction always asserts the LOCK# signal regardless of
    the |presence or absence of the LOCK prefix.

    What is a source of this? Intel, AMD or somebody else?

    This citation has been given many times now, but here it is yet
    again: That is the last sentence of the third paragraph in the
    "Description" section of the entry on the `LOCK` prefix in
    Volume 2A of the Intel SDM, order number 253668-093US (September
    2026), page 3-565. That volume can be downloaded from Intel at: https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg. I don't think that's
    what Intel intends and implements, but that's what a reading of their
    manual implies.

    Somehow, it does not imply it to me.

    Note that Anton said that it is an implication of _A_ reading
    of the manual, not of _ALL_ readings of the manual. Hence why
    it is ambiguous.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Sun Oct 18 18:25:08 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Michael S <[email protected]> wrote:
    [snip]
    When I want to know what particular insruction does I go to respective >section in Instruction Set Reference.
    I can believe that there exist other methodes, but I prefere mine.

    Unfortunately, that does not change the fact that there are
    multiple sections in the SDM that _can_ be read as mutually
    inconsistent with regards to the exact semantics of this
    particular operation.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Sun Oct 18 12:27:04 2026
    From Newsgroup: comp.arch

    On 10/16/2026 7:50 PM, Dan Cross wrote:
    In article <11au1vu$3ks5m$[email protected]>,
    Thomas Koenig <[email protected]> wrote:
    Dan Cross <[email protected]> schrieb:
    Unfortunately, the information is spread across two sections,
    and they contradict. The description in the `LOCK` prefix
    section in the latest version of the Intel SDM includes the text
    Anton quoted, while the description of `XCHG` itself makes clear
    that the destination operand must be a memory operand for the
    locking protocol to automatically apply. Which is correct?

    What would be the meaning of LOCK with memory operands? I can't
    think of any.

    Using the `LOCK` prefix without a destination operand that is a
    memory operand is an error, and the SDM is quite explicit about
    that. In fact, it says that an explicit `LOCK` prefix on an
    `XCHG` a register destination operand is _not_ permitted and
    "may" generate an `#UD` exception.

    But sadly, when talking about an `XCHG` _without_ an explicit
    operand, it is left ambiguous; all it says is that, "The `XCHG`
    instruction always asserts the `LOCK#` signal regardless of the
    presence or absence of the `LOCK` prefix." Devoid of the rest
    of the surrounding context, one could interpret that to mean
    that an `XCHG` _always_ forces a bus lock, irrespective of the
    type of its desintation operand.

    Why? I have no idea; as I said, I'm in the camp of going with
    what the description of `XCHG` itself says, and not the what the
    description of the `LOCK` prefix says: that sentence is _not_
    devoid of context, and besides, there has not been a physical
    `LOCK#` signal coming out of an Intel Xeon package since
    Nehalem.

    Try a LOCK RMW on memory that straddles a L2 cache line. That should
    trigger a full bus lock.





    I suppose one could imagine it forcing a poor-man's barrier to
    prevent later loads from being reorderd before it (loads can't
    migrate before locked instructions). But we've got explicit
    fence instructions for that, so I don't buy it.

    I suspect that sentence is just poorly phrased.

    - Dan C.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Sun Oct 18 21:04:41 2026
    From Newsgroup: comp.arch

    Michael S <[email protected]> writes:
    On Sun, 18 Oct 2026 16:57:26 GMT
    [email protected] (Anton Ertl) wrote:
    |The XCHG instruction always asserts the LOCK# signal regardless of
    the |presence or absence of the LOCK prefix.


    What is a source of this? Intel, AMD or somebody else?

    Intel, from (at least) the 1994 edition of the Pentium Processor
    User's Manual Vol 3., through the source of <https://www.felixcloutier.com/x86/lock>, to the latest SDM cited by
    Dan Cross.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Mon Oct 19 00:09:11 2026
    From Newsgroup: comp.arch

    I thought, though, that the main problem with Algol 68 was not that it
    was described poorly, but that although people were still able to
    understand the language well enough despite an unconventional formal description language... it was a large and complicated language,
    advancing the state of the art, and thus it was found difficult to
    implement.
    Hence, Pascal - a language which modernized Algol 60 without trying to
    be a language on an entirely new level.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Mon Oct 19 00:18:32 2026
    From Newsgroup: comp.arch

    On Sun, 18 Oct 2026 09:45:00 -0400, George Neuner
    <[email protected]> wrote:

    The problem with the original report was that they attempted with the
    grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs. A Turing-complete language can calculate anything,
    so how can it tell you that you were calculating this when you wanted
    to calculate that?

    Of course, with AI, we might be able to do something there.

    But already many modern languages do have strict type-checking.

    So even if Algol 68 was over-ambitious in this regard, trying to have
    the language help the programmer avoid more mistakes is basically a
    sound idea.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Mon Oct 19 01:46:21 2026
    From Newsgroup: comp.arch

    On Mon, 19 Oct 2026 00:09:11 GMT, John Savard wrote:

    I thought, though, that the main problem with Algol 68 was not that
    it was described poorly, but that although people were still able to understand the language well enough despite an unconventional formal description language... it was a large and complicated language,
    advancing the state of the art, and thus it was found difficult to
    implement.

    Algol 60 was a difficult language to implement less than a decade
    earlier. It was a driver of the state of the art back then, too.
    (And some still found it hard in 1968.)

    I think the form of the language specification played a big part in
    making it seem more intimidating than it was.

    Algol 68 would be a doddle to implement nowadays. In fact, Marcel Van
    Der Veer’s “Algol 68 Genie” implementation is being incorporated into GCC, I believe.

    Many of the terms pioneered in the Algol 68 specification did become
    popular -- which shows you how new those concepts were at the time:
    “heap”, “overload”, “dereference”. Others were not so popular: “transput” (for “I/O”), “name” (for “address”, would you believe),
    “mode” (for “type”).

    C took syntax words like “struct”, “void”, “int”, “long” and “short”
    straight from Algol 68.

    Hence, Pascal - a language which modernized Algol 60 without trying
    to be a language on an entirely new level.

    Niklaus Wirth was possibly the biggest critic of the Algol 68 effort.
    He and Tony Hoare had previously created Algol-W, which pioneered the
    concept of record structures (taking a simpler form than COBOL’s
    convoluted record structures). Pascal was basically the next step in
    the evolution of that.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Mon Oct 19 01:52:51 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    John Savard <[email protected]> wrote:
    On Sun, 18 Oct 2026 09:45:00 -0400, George Neuner
    <[email protected]> wrote:

    The problem with the original report was that they attempted with the >>grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs. A Turing-complete language can calculate anything,
    so how can it tell you that you were calculating this when you wanted
    to calculate that?

    With apologies, arguments like these always seem to me to miss
    the forest for the trees a bit. Some constructs clearly violate
    the documented semantics of e.g. a language.

    Yes, these langauges are all Turing-complete and so on, and no,
    we cannot solve _The_ Halting Problem, in all of its glorious
    generality. But, we can solve any number of specific halting
    _problems_. For example, I can see that, `for (;;);` is a loop
    that does not terminate. With enough effort, I can take that
    down some reasonably long paths.

    So, too, one can spot a lot of logic errors. There's no reason
    a compiler can't see this, for example:

    ? if (ptr == NULL) {
    ? int v = *ptr++;
    ? *ptr = v + 10;
    ? }

    And flag it with a error: "you dereferenced a pointer right
    after you asserted it was nil; did you invert the condition?"

    Similarly, I posted about Rust a few days ago, which can do all
    sorts of fun stuff with its borrow checker to assert that an
    object is still alive while references to it exist, and so on,
    and reject programs at compilation time that violate those
    semantics.

    Of course, with AI, we might be able to do something there.

    But already many modern languages do have strict type-checking.

    So even if Algol 68 was over-ambitious in this regard, trying to have
    the language help the programmer avoid more mistakes is basically a
    sound idea.

    Agreed. Indeed, we've gone much farther than just mere type
    checking.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Mon Oct 19 01:54:01 2026
    From Newsgroup: comp.arch

    On Mon, 19 Oct 2026 00:18:32 GMT, John Savard wrote:

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs. A Turing-complete language can calculate
    anything, so how can it tell you that you were calculating this when
    you wanted to calculate that?

    All the Algol 68 two-level grammar approach was trying to do was
    formalize rules that were already being spelled out in narrative text
    in other contemporary (and subsequent) language specifications. Basic
    things like
    * A name for something must be declared before it can be referenced.
    * Types of expected versus actual values must be compatible, with
    some predefined set of implicit conversions allowed (e.g.
    passing/assigning an integer where a float value is expected, but
    not the other way round).
    * A redeclaration of a name in an inner scope shadows (makes
    inaccessible for the duration) a definition in an outer scope.

    There was (and still is) the debate over what is “syntax” and what is “semantics”? Algol 68 was just trying to push the boundary to take
    some of what was thought to be “semantics” and show that it was just “syntax”, after all.

    So you see, they were not trying to do overly clever stuff like the
    Java compiler insisting that a variable could possibly be accessed
    before its first assignment, and this can’t be allowed, when it’s
    quite apparent to any human reader that can follow the program logic,
    that no such situation can occur.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From John Levine@[email protected] to comp.arch on Mon Oct 19 03:24:59 2026
    From Newsgroup: comp.arch

    According to Anton Ertl <[email protected]>:
    A team at the IBM Lab in Vienna made a formal specification for PL/I;
    I attended a lecture by Heinz Zemanek (the team leader) where he
    mentioned something about an implementor disagreeing with the formal >specification for recursion (disagreements between implementor and >specification can also happen with specifications written in a natural >language, so that may not say much). Anyway, ><https://en.wikipedia.org/wiki/PL/I#Standardization> says "The
    standard is couched as a formal definition[17] using a "PL/I
    Machine"[21] to specify the semantics." This sounds like the
    operational semantics that was developed by the IBM Lab Vienna, so
    maybe the standardization committee picked up this work. But it seems
    that the first standard never had a followon; was the definition too >unwieldy?

    I have a copy of the ANSI PL/I standard which uses VDL which I find close to impenetrable.

    The syntax part is OK but the semantics are endless definitions of something
    in terms of something else and I could never find the places where your program actually did anything.
    --
    Regards,
    John Levine, [email protected], Primary Perpetrator of "The Internet for Dummies",
    Please consider the environment before reading this e-mail. https://jl.ly
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Mon Oct 19 05:34:52 2026
    From Newsgroup: comp.arch

    John Levine <[email protected]> writes:
    According to Anton Ertl <[email protected]>:
    A team at the IBM Lab in Vienna made a formal specification for PL/I;
    I attended a lecture by Heinz Zemanek (the team leader) where he
    mentioned something about an implementor disagreeing with the formal >>specification for recursion (disagreements between implementor and >>specification can also happen with specifications written in a natural >>language, so that may not say much). Anyway, >><https://en.wikipedia.org/wiki/PL/I#Standardization> says "The
    standard is couched as a formal definition[17] using a "PL/I
    Machine"[21] to specify the semantics." This sounds like the
    operational semantics that was developed by the IBM Lab Vienna, so
    maybe the standardization committee picked up this work. But it seems
    that the first standard never had a followon; was the definition too >>unwieldy?

    I have a copy of the ANSI PL/I standard which uses VDL which I find close to impenetrable.

    Thanks. Yes, VDL is the specification language that the group at IBM
    Labs Vienna designed in order to define the formal semantics of PL/I
    (the V in VDL stands for Vienna). So the PL/I standard used their
    work.

    The syntax part is OK but the semantics are endless definitions of something >in terms of something else and I could never find the places where your program
    actually did anything.

    Interesting. I have seen this overfactoring in programs as well as natural-language specifications. Factoring is useful to avoid
    repeating stuff, but when you are interested in one specific thing,
    you would rather prefer that much of the factored-out stuff is
    inlined.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Sun Oct 18 23:43:47 2026
    From Newsgroup: comp.arch

    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Sun Oct 18 23:34:22 2026
    From Newsgroup: comp.arch

    Anton Ertl [2026-10-18 14:08:34] wrote:
    My take is that BNF was a big success in formalizing a part of a
    language. So what do you do when you are successful? You try to
    follow up on that. So they wanted to formalize more of the language,
    and go beyond the limits of BNF (context-free grammars) with Vw
    grammars. This was technically successful, but from a usability POV
    it was not.

    Yup. That was before type systems.

    Standard ML has been formally specified, and, given the audience of
    this language, if any programming language may have success going
    there, it should be a language like ML. There is a first revision
    (1990) and a second revision (1997), and SML seems to have reached the
    end of its evolution there.

    FWIW, I don't think the end of SML's evolution is a consequence of its
    having a formal spec, but admittedly, some of the factors that made it
    have a formal spec may have also been factors in the end of
    its evolution.

    Concerning terms like "semantic errors" or "static semantics" they
    make it appear that there is a fundamental difference between syntax
    and "static semantics" (the part that is not context-free and that is
    checked by the compiler). It seems to me that that's just a matter of
    what is expressed in the BNF.

    Agreed. The dividing line between lexical analysis, syntactic analysis,
    and "static semantics" mostly comes down to what is most convenient
    for a given set of tools: those things that work well with a regexp/DFA
    get handled in the lexical analysis, then those which work well with
    BNF/PEG are done in the syntactic analysis, and whatever's left over is
    dumped into the "static semantics".

    E.g., in Algol 60 the computation of conditions for if-statements have special BNF rules, whereas some later programming languages have
    a boolean type and putting a non-boolean between IF and THEN produces
    a type error, not a syntax error.

    Because in the mean time, people realized that moving it to types makes
    for a simpler grammar and in return they let you have a more flexible
    language where you can precompute those booleans into a variable that
    you later test in the if-statement.

    A related example would be `break` statements in C, which are allowed to
    occur only in loops and switch statements: you could encode that detail directly in the grammar, but it's usually considered easier to do it
    later on as a "static check" (more clear, less code). Not only it's
    simpler but it also makes it easier to emit meaningful error messages.


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Thomas Koenig@[email protected] to comp.arch on Mon Oct 19 07:44:25 2026
    From Newsgroup: comp.arch

    John Savard <[email protected]> schrieb:
    On Sun, 18 Oct 2026 09:45:00 -0400, George Neuner
    <[email protected]> wrote:

    The problem with the original report was that they attempted with the >>grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs.

    A Turing-complete language can calculate anything,
    so how can it tell you that you were calculating this when you wanted
    to calculate that?

    There are three possibilities: a) A formal verification can succeed,
    b) it can fail to make a determination, or c) it can show up bugs.

    c) is already implemented with many compiler warnings and errors,
    a simple example:

    $ cat do.f90
    program main
    implicit none
    integer :: i
    real, dimension(5) :: a
    do i=1,6
    a(i) = i + 2
    end do
    print *,a
    end

    $ gfortran do.f90
    do.f90:6:6:

    5 | do i=1,6
    | 2
    6 | a(i) = i + 2
    | 1
    Warning: Array reference at (1) out of bounds (6 > 5) in loop beginning at (2)

    If you develop code with formal verification and hit b), you have the
    option of not accepting the code.

    I believe Lean is a language which implements a) and shows missing
    goals for b), but I have never worked with it.
    --
    This USENET posting was made without artificial intelligence,
    artificial impertinence, artificial arrogance, artificial stupidity,
    artificial flavorings or artificial colorants.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From EricP@[email protected] to comp.arch on Mon Oct 19 09:38:11 2026
    From Newsgroup: comp.arch

    On 2026-Oct-18 15:27, Chris M. Thomasson wrote:

    Try a LOCK RMW on memory that straddles a L2 cache line. That should trigger a full bus lock.

    FYI there is an article measuring the effects of cache line split locks

    Investigating Split Locks on x86-64 https://chipsandcheese.com/p/investigating-split-locks-on-x86

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stephen Fuld@[email protected] to comp.arch on Mon Oct 19 06:57:48 2026
    From Newsgroup: comp.arch

    On 10/18/2026 8:43 PM, Stefan Monnier wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.


    === Stefan

    I believe this all started with empirical data from Anton showing
    different performance between Intel and AMD processors for XCHG
    reg,reg. There was some speculation that Intel asserted the lock
    protocol and that was the cause. The discussion then moved to at best confusing, and perhaps contradictory documentation. But has anyone
    addressed the original question?

    Specifically, do Intel processors actually do the lock stuff when it
    isn't necessary? If so, is the cause of the difference? If not, what
    is the cause?
    --
    - Stephen Fuld
    (e-mail address disguised to prevent spam)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From George Neuner@[email protected] to comp.arch on Mon Oct 19 14:50:57 2026
    From Newsgroup: comp.arch

    On Mon, 19 Oct 2026 01:52:51 -0000 (UTC),
    [email protected] (Dan Cross) wrote:

    In article <[email protected]>,
    John Savard <[email protected]> wrote:
    On Sun, 18 Oct 2026 09:45:00 -0400, George Neuner
    <[email protected]> wrote:

    The problem with the original report was that they attempted with the >>>grammar turn [at least some kinds of] semantic errors into syntax
    errors.

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs. A Turing-complete language can calculate anything,
    so how can it tell you that you were calculating this when you wanted
    to calculate that?

    With apologies, arguments like these always seem to me to miss
    the forest for the trees a bit. Some constructs clearly violate
    the documented semantics of e.g. a language.

    Yes, these langauges are all Turing-complete and so on, and no,
    we cannot solve _The_ Halting Problem, in all of its glorious
    generality. But, we can solve any number of specific halting
    _problems_. For example, I can see that, `for (;;);` is a loop
    that does not terminate. With enough effort, I can take that
    down some reasonably long paths.

    So, too, one can spot a lot of logic errors. There's no reason
    a compiler can't see this, for example:

    ? if (ptr == NULL) {
    ? int v = *ptr++;
    ? *ptr = v + 10;
    ? }

    And flag it with a error: "you dereferenced a pointer right
    after you asserted it was nil; did you invert the condition?"


    Absolutely compiler analysis can catch (some) semantic errors ... that
    never was in question.


    The problem with the *original* Algol68 report was that they tried to
    encode semantics using the syntax, the idea being that the parser then
    could catch semantic errors as syntax errors.

    The revised report changed direction: the syntax no longer tried to
    encode the semantics ... but it still was hard to read because the
    syntax definitions made copious /reference/ to semantics discussed in accompanying text.


    Similarly, I posted about Rust a few days ago, which can do all
    sorts of fun stuff with its borrow checker to assert that an
    object is still alive while references to it exist, and so on,
    and reject programs at compilation time that violate those
    semantics.

    Of course, with AI, we might be able to do something there.

    But already many modern languages do have strict type-checking.

    So even if Algol 68 was over-ambitious in this regard, trying to have
    the language help the programmer avoid more mistakes is basically a
    sound idea.

    Agreed. Indeed, we've gone much farther than just mere type
    checking.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Mon Oct 19 12:24:56 2026
    From Newsgroup: comp.arch

    John Savard [2026-10-19 00:18:32] wrote:
    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs.

    Compilers' ability to report errors mostly depend on the presence of
    redundancy in the source code. That redundancy depends can be
    influenced by the design of the language.

    So, in theory, a compiler can very much flag most logic errors in
    a program, simply by requiring all source code to come in two different
    forms (e.g. a "spec" and an "implementation") and to automatically
    verify that the two match.

    A Turing-complete language can calculate anything, so how can it tell
    you that you were calculating this when you wanted to calculate that?

    And the same still holds for non-Turing-complete languages, admittedly.


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Mon Oct 19 14:08:53 2026
    From Newsgroup: comp.arch

    On 10/19/2026 6:38 AM, EricP wrote:
    On 2026-Oct-18 15:27, Chris M. Thomasson wrote:

    Try a LOCK RMW on memory that straddles a L2 cache line. That should
    trigger a full bus lock.

    FYI there is an article measuring the effects of cache line split locks

    Investigating Split Locks on x86-64 https://chipsandcheese.com/p/investigating-split-locks-on-x86


    I see. Actually, a way to "abuse" it even further is to use a LOCK RMW,
    say even LOCK XADD on something that straddles a cache line issues a bus
    lock. So, I have seen some papers on abusing QPI to gain a remote memory barrier or async sync for things like RCU. FlushProcessWriteBuffers
    (windows way), I forgot the damn Linux thing. I think it might be sys_membarrier...
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@[email protected] to comp.arch on Mon Oct 19 21:21:03 2026
    From Newsgroup: comp.arch

    On Mon, 19 Oct 2026 14:08:53 -0700, Chris M. Thomasson wrote:

    I forgot the damn Linux thing. I think it might be sys_membarrier...

    <https://manpages.debian.org/membarrier(2)> ?
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Mon Oct 19 14:26:20 2026
    From Newsgroup: comp.arch

    On 10/19/2026 2:21 PM, Lawrence D’Oliveiro wrote:
    On Mon, 19 Oct 2026 14:08:53 -0700, Chris M. Thomasson wrote:

    I forgot the damn Linux thing. I think it might be sys_membarrier...

    <https://manpages.debian.org/membarrier(2)> ?

    Has to be it. Afaict, its a way to help algorithms like RCU, or
    basically any async sync pattern. Say the readers are cheap, the writers
    not so cheap... Fwiw, here is the windows side of the coin:

    https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushprocesswritebuffers
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Mon Oct 19 14:27:33 2026
    From Newsgroup: comp.arch

    On 10/19/2026 6:57 AM, Stephen Fuld wrote:
    On 10/18/2026 8:43 PM, Stefan Monnier wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence.  It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.


    === Stefan

    I believe this all started with empirical data from Anton showing
    different performance between Intel and AMD processors for XCHG
    reg,reg.  There was some speculation that Intel asserted the lock
    protocol and that was the cause.  The discussion then moved to at best confusing, and perhaps contradictory documentation.  But has anyone addressed the original question?

    Specifically, do Intel processors actually do the lock stuff when it
    isn't necessary?  If so, is the cause of the difference?  If not, what
    is the cause?


    Bingo! Tango, Locked on.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Joseph Seigh@[email protected] to comp.arch on Mon Oct 19 19:17:14 2026
    From Newsgroup: comp.arch

    On 10/19/26 5:08 PM, Chris M. Thomasson wrote:
    On 10/19/2026 6:38 AM, EricP wrote:
    On 2026-Oct-18 15:27, Chris M. Thomasson wrote:

    Try a LOCK RMW on memory that straddles a L2 cache line. That should
    trigger a full bus lock.

    FYI there is an article measuring the effects of cache line split locks

    Investigating Split Locks on x86-64
    https://chipsandcheese.com/p/investigating-split-locks-on-x86


    I see. Actually, a way to "abuse" it even further is to use a LOCK RMW,
    say even LOCK XADD on something that straddles a cache line issues a bus lock. So, I have seen some papers on abusing QPI to gain a remote memory barrier or async sync for things like RCU. FlushProcessWriteBuffers
    (windows way), I forgot the damn Linux thing. I think it might be sys_membarrier...


    You are thinking of IPI (inter processsor interrupt) maybe? membarrier
    changed to that apparently because the quiesce points used by the RCU implementation of membarrier weren't frequent enough.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Tue Oct 20 02:00:48 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.

    The effects of a bus lock include disallowing memory operations
    (except for instruction fetches or page table accesses) passing
    a locked operation. If `XCHG reg,reg` where indeed treated as
    though it asserted `LOCK#` for the duration of its execution, it
    could be (ab)used to force that behavior: From sec 11.1.2.2 of
    SDM Volume 3a (Sept 2026 version):

    |Locked operations are atomic with respect to all other memory
    |operations and all externally visible events. Only instruction
    |fetch and page table accesses can pass locked instructions.
    |Locked instructions can be used to synchronize data written by
    |one processor and read by another processor.

    For example, this could be used before releasing a lock to
    prevent a load from migrating into the critical section (though
    on a TSO machine this should be ok, since a load can't be
    reordered before a store to the same location).

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Tue Oct 20 02:05:05 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    George Neuner <[email protected]> wrote:
    On Mon, 19 Oct 2026 01:52:51 -0000 (UTC),
    [email protected] (Dan Cross) wrote:

    In article <[email protected]>,
    John Savard <[email protected]> wrote:
    On Sun, 18 Oct 2026 09:45:00 -0400, George Neuner
    <[email protected]> wrote:

    The problem with the original report was that they attempted with the >>>>grammar turn [at least some kinds of] semantic errors into syntax >>>>errors.

    Obviously, there's no way one can enable a compiler to flag logic
    errors in programs. A Turing-complete language can calculate anything,
    so how can it tell you that you were calculating this when you wanted
    to calculate that?

    With apologies, arguments like these always seem to me to miss
    the forest for the trees a bit. Some constructs clearly violate
    the documented semantics of e.g. a language.

    Yes, these langauges are all Turing-complete and so on, and no,
    we cannot solve _The_ Halting Problem, in all of its glorious
    generality. But, we can solve any number of specific halting
    _problems_. For example, I can see that, `for (;;);` is a loop
    that does not terminate. With enough effort, I can take that
    down some reasonably long paths.

    So, too, one can spot a lot of logic errors. There's no reason
    a compiler can't see this, for example:

    ? if (ptr == NULL) {
    ? int v = *ptr++;
    ? *ptr = v + 10;
    ? }

    And flag it with a error: "you dereferenced a pointer right
    after you asserted it was nil; did you invert the condition?"

    Absolutely compiler analysis can catch (some) semantic errors ... that
    never was in question.

    Sorry, I was referring specifically to the factually incorrect
    statement that "there's no way one can enable a compiler to flag
    logic errors in programs," quoted above, which is flatly
    incorrect.

    The problem with the *original* Algol68 report was that they tried to
    encode semantics using the syntax, the idea being that the parser then
    could catch semantic errors as syntax errors.

    The revised report changed direction: the syntax no longer tried to
    encode the semantics ... but it still was hard to read because the
    syntax definitions made copious /reference/ to semantics discussed in >accompanying text.

    Oophf. Sounds painful.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Mon Oct 19 22:41:54 2026
    From Newsgroup: comp.arch

    On 10/19/2026 4:17 PM, Joseph Seigh wrote:
    On 10/19/26 5:08 PM, Chris M. Thomasson wrote:
    On 10/19/2026 6:38 AM, EricP wrote:
    On 2026-Oct-18 15:27, Chris M. Thomasson wrote:

    Try a LOCK RMW on memory that straddles a L2 cache line. That should
    trigger a full bus lock.

    FYI there is an article measuring the effects of cache line split locks

    Investigating Split Locks on x86-64
    https://chipsandcheese.com/p/investigating-split-locks-on-x86


    I see. Actually, a way to "abuse" it even further is to use a LOCK
    RMW, say even LOCK XADD on something that straddles a cache line
    issues a bus lock. So, I have seen some papers on abusing QPI to gain
    a remote memory barrier or async sync for things like RCU.
    FlushProcessWriteBuffers (windows way), I forgot the damn Linux thing.
    I think it might be sys_membarrier...


    You are thinking of IPI (inter processsor interrupt) maybe?  membarrier changed to that apparently because the quiesce points used by the RCU implementation of membarrier weren't frequent enough.

    I remember reading a paper from somebody, was it Dice? Damn! Cannot
    remember right now. That abused the QPI, I think the quick path
    interconnect, to give them a "remote" membar to implement async algos.
    Iirc they used misaligned LOCK RMW on something that straddled a l2
    cache line to make the system assert a bus lock. I know I read the damn
    paper but it was way back. Iiirc around 2006-2008 ish? I cannot remember.

    The IPI uses things like FlushProcessWriteBuffers over on Windows, Linux
    has one to.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.arch on Tue Oct 20 14:09:20 2026
    From Newsgroup: comp.arch

    [email protected] (Dan Cross) writes:
    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.

    The effects of a bus lock include disallowing memory operations
    (except for instruction fetches or page table accesses) passing
    a locked operation. If `XCHG reg,reg` where indeed treated as
    though it asserted `LOCK#` for the duration of its execution, it
    could be (ab)used to force that behavior: From sec 11.1.2.2 of
    SDM Volume 3a (Sept 2026 version):


    It's worth noting that AMD processors (in the 2008 timeframe) would
    assert the LOCK# signal if a highly contended cache line could not
    be acquired in exclusive mode within a certain window of time,
    even if the access was completely encapsulated in said cache line.

    I suspect that is still the case.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From MitchAlsup@[email protected] to comp.arch on Tue Oct 20 16:45:20 2026
    From Newsgroup: comp.arch

    "Chris M. Thomasson" <[email protected]> posted:

    On 10/19/2026 4:17 PM, Joseph Seigh wrote:
    On 10/19/26 5:08 PM, Chris M. Thomasson wrote:
    On 10/19/2026 6:38 AM, EricP wrote:
    On 2026-Oct-18 15:27, Chris M. Thomasson wrote:

    Try a LOCK RMW on memory that straddles a L2 cache line. That should >>>> trigger a full bus lock.

    FYI there is an article measuring the effects of cache line split locks >>>
    Investigating Split Locks on x86-64
    https://chipsandcheese.com/p/investigating-split-locks-on-x86


    I see. Actually, a way to "abuse" it even further is to use a LOCK
    RMW, say even LOCK XADD on something that straddles a cache line
    issues a bus lock. So, I have seen some papers on abusing QPI to gain
    a remote memory barrier or async sync for things like RCU.
    FlushProcessWriteBuffers (windows way), I forgot the damn Linux thing.
    I think it might be sys_membarrier...


    You are thinking of IPI (inter processsor interrupt) maybe?  membarrier changed to that apparently because the quiesce points used by the RCU implementation of membarrier weren't frequent enough.

    I remember reading a paper from somebody, was it Dice? Damn! Cannot
    remember right now. That abused the QPI, I think the quick path interconnect, to give them a "remote" membar to implement async algos.
    Iirc they used misaligned LOCK RMW on something that straddled a l2
    cache line to make the system assert a bus lock. I know I read the damn paper but it was way back. Iiirc around 2006-2008 ish? I cannot remember.

    The IPI uses things like FlushProcessWriteBuffers over on Windows, Linux
    has one to.

    In My 66000, an IPI is a write to MM I/O space and is sequentially
    consistent, so all older writes leave the core prior to the MM I/O
    leaving the core.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Tue Oct 20 10:05:57 2026
    From Newsgroup: comp.arch

    Dan Cross [2026-10-20 02:00:48] wrote:
    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    How could code witness the difference?
    The effects of a bus lock include disallowing memory operations
    (except for instruction fetches or page table accesses) passing
    a locked operation.

    Ah, so it doesn't just make the operation atomic, but it additionally
    imposes barrier-style restrictions on reordering surrounding memory
    operations? I see, thanks.


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stefan Monnier@[email protected] to comp.arch on Tue Oct 20 10:00:15 2026
    From Newsgroup: comp.arch

    Stephen Fuld [2026-10-19 06:57:48] wrote:
    On 10/18/2026 8:43 PM, Stefan Monnier wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.
    How could code witness the difference?
    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.
    === Stefan
    I believe this all started with empirical data from Anton showing different performance between Intel and AMD processors for XCHG reg,reg.

    Indeed but my question is about the ISA definition, i.e. independent
    from any specific implementation.


    === Stefan
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@[email protected] (Dan Cross) to comp.arch on Tue Oct 20 19:56:43 2026
    From Newsgroup: comp.arch

    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    Dan Cross [2026-10-20 02:00:48] wrote:
    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    How could code witness the difference?
    The effects of a bus lock include disallowing memory operations
    (except for instruction fetches or page table accesses) passing
    a locked operation.

    Ah, so it doesn't just make the operation atomic, but it additionally
    imposes barrier-style restrictions on reordering surrounding memory >operations? I see, thanks.

    Well, to be clear, I don't think that _that particular form_ of
    `xchg` actually does. But if the destination were a memory
    operand, it would, yes. :-)

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Chris M. Thomasson@[email protected] to comp.arch on Tue Oct 20 16:44:11 2026
    From Newsgroup: comp.arch

    On 10/20/2026 7:09 AM, Scott Lurndal wrote:
    [email protected] (Dan Cross) writes:
    In article <[email protected]>,
    Stefan Monnier <[email protected]> wrote:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg", >>>> the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    I believe AMD can claim that its behavior is consistent with the
    behavior you'd get when asserting the LOCK# signal.

    The effects of a bus lock include disallowing memory operations
    (except for instruction fetches or page table accesses) passing
    a locked operation. If `XCHG reg,reg` where indeed treated as
    though it asserted `LOCK#` for the duration of its execution, it
    could be (ab)used to force that behavior: From sec 11.1.2.2 of
    SDM Volume 3a (Sept 2026 version):


    It's worth noting that AMD processors (in the 2008 timeframe) would
    assert the LOCK# signal if a highly contended cache line could not
    be acquired in exclusive mode within a certain window of time,
    even if the access was completely encapsulated in said cache line.

    I suspect that is still the case.

    I almost have to agree. I think it was there for some sort of anti livelock...? Try bashing the shit out of a LOCK CMPXCHG with another
    thread just writing to the address trying to make the CAS fail, over and
    over again... It might force some internal logic to assert a real bus lock.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Wed Oct 21 14:15:04 2026
    From Newsgroup: comp.arch

    On Mon, 19 Oct 2026 01:46:21 -0000 (UTC), Lawrence =?iso-8859-13?q?D=FFOliveiro?= <[email protected]d> wrote:

    Niklaus Wirth was possibly the biggest critic of the Algol 68 effort.
    He and Tony Hoare had previously created Algol-W, which pioneered the
    concept of record structures (taking a simpler form than COBOL’s
    convoluted record structures). Pascal was basically the next step in
    the evolution of that.

    And, of course, one might mention MODULA-2, which took certain
    advanced ideas seen in Ada and put them in a Pascal-like context.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Niklas Holsti@[email protected] to comp.arch on Wed Oct 21 18:34:46 2026
    From Newsgroup: comp.arch

    On 2026-10-21 17:15, John Savard wrote:
    On Mon, 19 Oct 2026 01:46:21 -0000 (UTC), Lawrence =?iso-8859-13?q?D=FFOliveiro?= <[email protected]d> wrote:

    Niklaus Wirth was possibly the biggest critic of the Algol 68 effort.
    He and Tony Hoare had previously created Algol-W, which pioneered the
    concept of record structures (taking a simpler form than COBOL’s
    convoluted record structures). Pascal was basically the next step in
    the evolution of that.

    And, of course, one might mention MODULA-2, which took certain
    advanced ideas seen in Ada and put them in a Pascal-like context.

    My understanding is that the influences went from Modula-2 to Ada, and Wikipedia agrees with me, saying that Modula-2 first appeared in 1978.
    The development of these languages overlapped in time, but Modula-2 was finalized and published before Ada.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From quadibloc@[email protected] (John Savard) to comp.arch on Wed Oct 21 19:38:00 2026
    From Newsgroup: comp.arch

    On Wed, 21 Oct 2026 18:34:46 +0300, Niklas Holsti <[email protected]d> wrote:

    My understanding is that the influences went from Modula-2 to Ada, and >Wikipedia agrees with me, saying that Modula-2 first appeared in 1978.

    You're quite right. I searched for more information, and apparently
    Concurrent Pascal was "first", with MODULA-2 coming very shortly
    after. And then, after the two competing models of those languages
    were discussed for a while, Ada included the feature as well.

    However, one source claimed that PL/I should really be given the
    credit for including parallel constructs well before Concurrent
    Pascal.

    John Savard
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From aph@[email protected] to comp.arch on Thu Oct 22 09:51:38 2026
    From Newsgroup: comp.arch

    John Savard <[email protected]> wrote:
    On Wed, 21 Oct 2026 18:34:46 +0300, Niklas Holsti <[email protected]d> wrote:

    My understanding is that the influences went from Modula-2 to Ada, and >>Wikipedia agrees with me, saying that Modula-2 first appeared in 1978.

    You're quite right. I searched for more information, and apparently Concurrent Pascal was "first", with MODULA-2 coming very shortly
    after. And then, after the two competing models of those languages
    were discussed for a while, Ada included the feature as well.

    However, one source claimed that PL/I should really be given the
    credit for including parallel constructs well before Concurrent
    Pascal.

    I think that's a rather IBM-centric view. The Burroughs B5000 (after
    1961) OS was written in an Algol dialect called ESPOL, which
    necessarily had concurrency support. The first production PL/I
    compiler shipped in 1966.

    Andrew.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From anton@[email protected] (Anton Ertl) to comp.arch on Thu Oct 22 10:54:04 2026
    From Newsgroup: comp.arch

    Stefan Monnier <[email protected]> writes:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg, reg",
    the assertion of the LOCK# signal still has to occur, and that's why
    Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    Depends on the hardware. If there is some device connected t the
    LOCK# signal (e.g., another CPU), and that behaves differently when
    the signal is asserted, the code can measure that.

    - anton
    --
    'Anyone trying for "industrial quality" ISA should avoid undefined behavior.'
    Mitch Alsup, <[email protected]>
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Michael S@[email protected] to comp.arch on Thu Oct 22 22:11:32 2026
    From Newsgroup: comp.arch

    On Thu, 22 Oct 2026 10:54:04 GMT
    [email protected] (Anton Ertl) wrote:

    Stefan Monnier <[email protected]> writes:
    Anton Ertl [2026-10-18 16:57:26] wrote:
    And actually all the stuff about XCHG with memory operands does not
    contradict this sentence. It could be understood as meaning that
    while all the other aspects of locking don't apply to "XCHG reg,
    reg", the assertion of the LOCK# signal still has to occur, and
    that's why Intel processors implement a slow XCHG reg, reg.

    How could code witness the difference?

    Depends on the hardware. If there is some device connected t the
    LOCK# signal (e.g., another CPU), and that behaves differently when
    the signal is asserted, the code can measure that.

    - anton

    My undersanding is that in server x86 CPU physical LOCK# signal does not
    exist for more than decade. Probably much longer in desktop and laptop
    devices.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Stephen Fuld@[email protected] to comp.arch on Thu Oct 22 14:15:57 2026
    From Newsgroup: comp.arch

    On 10/21/2026 12:38 PM, John Savard wrote:
    On Wed, 21 Oct 2026 18:34:46 +0300, Niklas Holsti <[email protected]d> wrote:

    My understanding is that the influences went from Modula-2 to Ada, and
    Wikipedia agrees with me, saying that Modula-2 first appeared in 1978.

    You're quite right. I searched for more information, and apparently Concurrent Pascal was "first", with MODULA-2 coming very shortly
    after. And then, after the two competing models of those languages
    were discussed for a while, Ada included the feature as well.

    However, one source claimed that PL/I should really be given the
    credit for including parallel constructs well before Concurrent
    Pascal.

    I vaguely recall that there was an optional feature in the COBOL
    standard for concurrent processing, or something like that. It wasn't implemented in the compiler I used and I never investigated exactly what
    it was. But it certainly predated Pascal, Ad and other such languages.

    Does anyone else know anything about this?
    --
    - Stephen Fuld
    (e-mail address disguised to prevent spam)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@[email protected] (Scott Lurndal) to comp.arch on Fri Oct 23 14:08:09 2026
    From Newsgroup: comp.arch

    Stephen Fuld <[email protected]d> writes:
    On 10/21/2026 12:38 PM, John Savard wrote:
    On Wed, 21 Oct 2026 18:34:46 +0300, Niklas Holsti
    <[email protected]d> wrote:

    My understanding is that the influences went from Modula-2 to Ada, and
    Wikipedia agrees with me, saying that Modula-2 first appeared in 1978.

    You're quite right. I searched for more information, and apparently
    Concurrent Pascal was "first", with MODULA-2 coming very shortly
    after. And then, after the two competing models of those languages
    were discussed for a while, Ada included the feature as well.

    However, one source claimed that PL/I should really be given the
    credit for including parallel constructs well before Concurrent
    Pascal.

    I vaguely recall that there was an optional feature in the COBOL
    standard for concurrent processing, or something like that. It wasn't >implemented in the compiler I used and I never investigated exactly what
    it was. But it certainly predated Pascal, Ad and other such languages.

    Does anyone else know anything about this?

    Burroughs added concurrent programming extensions to COBOL74 back
    in the 70's. USAGE IS TASK, for example; also the PROCESS verb
    was added.
    --- Synchronet 3.22a-Linux NewsLink 1.2