Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch > #118579 > unrolled thread
| Started by | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| First post | 2026-10-13 08:43 +0000 |
| Last post | 2026-10-20 16:45 +0000 |
| Articles | 20 on this page of 81 — 18 participants |
Back to article view | Back to comp.arch
Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-13 08:43 +0000
Re: Performance of xchg reg,reg Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-14 00:23 +0000
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-14 07:00 +0000
Re: Performance of xchg reg,reg MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-14 22:35 +0000
Re: Performance of xchg reg,reg Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-14 23:07 +0000
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-15 06:05 +0000
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-15 07:06 +0000
Re: Performance of xchg reg,reg EricP <ThatWouldBeTelling@thevillage.com> - 2026-10-16 09:47 -0400
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-16 16:04 +0000
Re: Performance of xchg reg,reg Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-17 05:46 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-14 22:29 +0300
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-15 14:21 -0700
Re: Performance of xchg reg,reg Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-15 21:42 +0000
Re: Performance of xchg reg,reg Terje Mathisen <terje.mathisen@tmsw.no> - 2026-10-16 14:45 +0200
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-16 05:50 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-16 11:34 +0300
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-16 18:23 +0000
Re: Performance of xchg reg,reg scott@slp53.sl.home (Scott Lurndal) - 2026-10-16 20:48 +0000
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-16 14:28 -0700
Re: Performance of xchg reg,reg Thomas Koenig <tkoenig@netcologne.de> - 2026-10-17 09:48 +0000
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-17 02:50 +0000
Re: Performance of xchg reg,reg MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-17 17:11 +0000
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-17 17:31 +0000
Re: Performance of xchg reg,reg MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-17 19:39 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-17 23:20 +0300
Re: Documentation (was Re: Performance of xchg reg,reg) Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-17 20:54 +0000
Re: Documentation (was Re: Performance of xchg reg,reg) George Neuner <gneuner2@comcast.net> - 2026-10-18 09:45 -0400
Algol 68 (was: Documentation (was Re: Performance of xchg reg,reg)) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-18 14:08 +0000
Re: Algol 68 (was: Documentation (was Re: Performance of xchg reg,reg)) quadibloc@invalid.com (John Savard) - 2026-10-19 00:09 +0000
Re: Algol 68 (was Re: Documentation) Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-19 01:46 +0000
Re: Algol 68 (was Re: Documentation) quadibloc@invalid.com (John Savard) - 2026-10-21 14:15 +0000
Re: Algol 68 (was Re: Documentation) Niklas Holsti <niklas.holsti@tidorum.invalid> - 2026-10-21 18:34 +0300
Re: Algol 68 (was Re: Documentation) quadibloc@invalid.com (John Savard) - 2026-10-21 19:38 +0000
Re: Algol 68 (was Re: Documentation) aph@littlepinkcloud.invalid - 2026-10-22 09:51 +0000
Re: Algol 68 (was Re: Documentation) Stephen Fuld <sfuld@alumni.cmu.edu.invalid> - 2026-10-22 14:15 -0700
Re: Algol 68 (was Re: Documentation) scott@slp53.sl.home (Scott Lurndal) - 2026-10-23 14:08 +0000
Re: PL/I, was Algol 68 (was: Documentation (was Re: Performance of xchg reg,reg)) John Levine <johnl@taugh.com> - 2026-10-19 03:24 +0000
Re: PL/I, was Algol 68 (was: Documentation (was Re: Performance of xchg reg,reg)) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-19 05:34 +0000
Re: Algol 68 Stefan Monnier <monnier@iro.umontreal.ca> - 2026-10-18 23:34 -0400
Re: Documentation (was Re: Performance of xchg reg,reg) quadibloc@invalid.com (John Savard) - 2026-10-19 00:18 +0000
Re: Documentation (was Re: Performance of xchg reg,reg) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-19 01:52 +0000
Re: Documentation (was Re: Performance of xchg reg,reg) George Neuner <gneuner2@comcast.net> - 2026-10-19 14:50 -0400
Re: Documentation (was Re: Performance of xchg reg,reg) cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-20 02:05 +0000
Re: Algol 68 (was Re: Documentation) Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-19 01:54 +0000
Re: Documentation (was Re: Performance of xchg reg,reg) Thomas Koenig <tkoenig@netcologne.de> - 2026-10-19 07:44 +0000
Re: Documentation (was Re: Performance of xchg reg,reg) Stefan Monnier <monnier@iro.umontreal.ca> - 2026-10-19 12:24 -0400
Re: Documentation (was Re: Performance of xchg reg,reg) MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-18 17:48 +0000
Re: Performance of xchg reg,reg George Neuner <gneuner2@comcast.net> - 2026-10-18 08:59 -0400
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-18 15:08 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-18 18:43 +0300
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-18 16:57 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-18 20:47 +0300
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 18:07 +0000
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-18 21:04 +0000
Re: Performance of xchg reg,reg Stefan Monnier <monnier@iro.umontreal.ca> - 2026-10-18 23:43 -0400
Re: Performance of xchg reg,reg Stephen Fuld <sfuld@alumni.cmu.edu.invalid> - 2026-10-19 06:57 -0700
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-19 14:27 -0700
Re: Performance of xchg reg,reg Stefan Monnier <monnier@iro.umontreal.ca> - 2026-10-20 10:00 -0400
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-20 02:00 +0000
Re: Performance of xchg reg,reg scott@slp53.sl.home (Scott Lurndal) - 2026-10-20 14:09 +0000
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-20 16:44 -0700
Re: Performance of xchg reg,reg Stefan Monnier <monnier@iro.umontreal.ca> - 2026-10-20 10:05 -0400
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-20 19:56 +0000
Re: Performance of xchg reg,reg anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-10-22 10:54 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-22 22:11 +0300
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 17:40 +0000
Re: Performance of xchg reg,reg Michael S <already5chosen@yahoo.com> - 2026-10-18 20:54 +0300
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 18:25 +0000
Re: Performance of xchg reg,reg MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-18 18:01 +0000
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 17:59 +0000
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 17:09 +0000
Re: Performance of xchg reg,reg EricP <ThatWouldBeTelling@thevillage.com> - 2026-10-18 12:31 -0400
Re: Performance of xchg reg,reg cross@spitfire.i.gajendra.net (Dan Cross) - 2026-10-18 17:47 +0000
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-18 12:27 -0700
Re: Performance of xchg reg,reg EricP <ThatWouldBeTelling@thevillage.com> - 2026-10-19 09:38 -0400
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-19 14:08 -0700
Re: Performance of xchg reg,reg Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-10-19 21:21 +0000
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-19 14:26 -0700
Re: Performance of xchg reg,reg Joseph Seigh <jseigh_es00@xemaps.com> - 2026-10-19 19:17 -0400
Re: Performance of xchg reg,reg "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-10-19 22:41 -0700
Re: Performance of xchg reg,reg MitchAlsup <user5857@newsgrouper.org.invalid> - 2026-10-20 16:45 +0000
Page 1 of 5 [1] 2 3 4 5 Next page →
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-13 08:43 +0000 |
| Subject | Performance of xchg reg,reg |
| Message-ID | <2026Oct13.104347@mips.complang.tuwien.ac.at> |
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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-10-14 00:23 +0000 |
| Message-ID | <11ami2v$11dqu$3@dont-email.me> |
| In reply to | #118579 |
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 ...
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-14 07:00 +0000 |
| Message-ID | <2026Oct14.090023@mips.complang.tuwien.ac.at> |
| In reply to | #118597 |
Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> 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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [prev] | [next] | [standalone]
| From | MitchAlsup <user5857@newsgrouper.org.invalid> |
|---|---|
| Date | 2026-10-14 22:35 +0000 |
| Message-ID | <1792017353-5857@newsgrouper.org> |
| In reply to | #118603 |
anton@mips.complang.tuwien.ac.at (Anton Ertl) posted: > /ERROR "unexpected byte sequence starting at index 607: '\xE2'" while decoding/: > > Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> 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
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-10-14 23:07 +0000 |
| Message-ID | <11ap1un$1tsnt$2@dont-email.me> |
| In reply to | #118625 |
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>
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-15 06:05 +0000 |
| Message-ID | <2026Oct15.080534@mips.complang.tuwien.ac.at> |
| In reply to | #118625 |
MitchAlsup <user5857@newsgrouper.org.invalid> 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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-15 07:06 +0000 |
| Message-ID | <2026Oct15.090653@mips.complang.tuwien.ac.at> |
| In reply to | #118631 |
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>MitchAlsup <user5857@newsgrouper.org.invalid> 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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [prev] | [next] | [standalone]
| From | EricP <ThatWouldBeTelling@thevillage.com> |
|---|---|
| Date | 2026-10-16 09:47 -0400 |
| Message-ID | <2WpAS.163763$Zbg.15006@fx35.iad> |
| In reply to | #118634 |
On 2026-Oct-15 03:06, Anton Ertl wrote:
> anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>> MitchAlsup <user5857@newsgrouper.org.invalid> 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
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-16 16:04 +0000 |
| Message-ID | <2026Oct16.180410@mips.complang.tuwien.ac.at> |
| In reply to | #118651 |
EricP <ThatWouldBeTelling@thevillage.com> 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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-10-17 05:46 +0000 |
| Message-ID | <11av23o$3ubmb$1@dont-email.me> |
| In reply to | #118651 |
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 ...
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2026-10-14 22:29 +0300 |
| Message-ID | <20261014222914.0000399e@yahoo.com> |
| In reply to | #118579 |
On Tue, 13 Oct 2026 08:43:47 GMT anton@mips.complang.tuwien.ac.at (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.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-10-15 14:21 -0700 |
| Message-ID | <11arg45$2p70p$1@dont-email.me> |
| In reply to | #118579 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-10-15 21:42 +0000 |
| Message-ID | <11arhcb$2p8h1$7@dont-email.me> |
| In reply to | #118643 |
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 ...
[toc] | [prev] | [next] | [standalone]
| From | Terje Mathisen <terje.mathisen@tmsw.no> |
|---|---|
| Date | 2026-10-16 14:45 +0200 |
| Message-ID | <11at6a2$39q08$1@dont-email.me> |
| In reply to | #118644 |
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"
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-10-16 05:50 +0000 |
| Message-ID | <2026Oct16.075055@mips.complang.tuwien.ac.at> |
| In reply to | #118643 |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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, <c17fcd89-f024-40e7-a594-88a85ac10d20o@googlegroups.com>
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2026-10-16 11:34 +0300 |
| Message-ID | <20261016113441.00002a5f@yahoo.com> |
| In reply to | #118646 |
On Fri, 16 Oct 2026 05:50:55 GMT anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote: > "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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.
[toc] | [prev] | [next] | [standalone]
| From | cross@spitfire.i.gajendra.net (Dan Cross) |
|---|---|
| Date | 2026-10-16 18:23 +0000 |
| Message-ID | <11atq3a$nqi$1@reader2.panix.com> |
| In reply to | #118649 |
In article <20261016113441.00002a5f@yahoo.com>, Michael S <already5chosen@yahoo.com> wrote: >On Fri, 16 Oct 2026 05:50:55 GMT >anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote: > >> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2026-10-16 20:48 +0000 |
| Message-ID | <g4wAS.119956$2%g.24960@fx41.iad> |
| In reply to | #118656 |
Thomas Koenig <tkoenig@netcologne.de> writes: >Dan Cross <cross@spitfire.i.gajendra.net> schrieb: >> In article <20261016113441.00002a5f@yahoo.com>, >> Michael S <already5chosen@yahoo.com> wrote: >>>On Fri, 16 Oct 2026 05:50:55 GMT >>>anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote: >>> >>>> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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?
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-10-16 14:28 -0700 |
| Message-ID | <11au4u4$3llb5$1@dont-email.me> |
| In reply to | #118661 |
On 10/16/2026 1:48 PM, Scott Lurndal wrote: > Thomas Koenig <tkoenig@netcologne.de> writes: >> Dan Cross <cross@spitfire.i.gajendra.net> schrieb: >>> In article <20261016113441.00002a5f@yahoo.com>, >>> Michael S <already5chosen@yahoo.com> wrote: >>>> On Fri, 16 Oct 2026 05:50:55 GMT >>>> anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote: >>>> >>>>> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Koenig <tkoenig@netcologne.de> |
|---|---|
| Date | 2026-10-17 09:48 +0000 |
| Message-ID | <11avg8t$2skj$1@dont-email.me> |
| In reply to | #118661 |
Scott Lurndal <scott@slp53.sl.home> schrieb: > Thomas Koenig <tkoenig@netcologne.de> writes: >>Dan Cross <cross@spitfire.i.gajendra.net> schrieb: >>> In article <20261016113441.00002a5f@yahoo.com>, >>> Michael S <already5chosen@yahoo.com> wrote: >>>>On Fri, 16 Oct 2026 05:50:55 GMT >>>>anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote: >>>> >>>>> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> 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.
[toc] | [prev] | [next] | [standalone]
Page 1 of 5 [1] 2 3 4 5 Next page →
Back to top | Article view | comp.arch
csiph-web