Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #82547 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2021-12-05 18:13 +0100 |
| Last post | 2021-12-08 09:08 +0100 |
| Articles | 20 on this page of 27 — 8 participants |
Back to article view | Back to comp.lang.c++
Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-05 18:13 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-12-05 19:56 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-05 15:22 -0800
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-12-05 23:43 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-05 19:31 -0800
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-06 06:26 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-06 06:24 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-12-06 10:45 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-06 13:09 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-06 06:27 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-06 18:02 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-07 06:27 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-07 18:06 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-07 19:14 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-07 18:49 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-07 19:54 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-07 19:14 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-07 19:25 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-08 09:50 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-08 00:59 -0800
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-08 15:41 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak scott@slp53.sl.home (Scott Lurndal) - 2021-12-08 15:48 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Bonita Montero <Bonita.Montero@gmail.com> - 2021-12-08 17:35 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Öö Tiib <ootiib@hot.ee> - 2021-12-08 10:57 -0800
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Manfred <noname@add.invalid> - 2021-12-09 00:27 +0100
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak Juha Nieminen <nospam@thanks.invalid> - 2021-12-09 06:30 +0000
Re: Little program to test concurrency of .fetch_add and .compare_exchange_weak David Brown <david.brown@hesbynett.no> - 2021-12-08 09:08 +0100
Page 1 of 2 [1] 2 Next page →
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-05 18:13 +0100 |
| Subject | Little program to test concurrency of .fetch_add and .compare_exchange_weak |
| Message-ID | <soirv4$57v$1@dont-email.me> |
I've written a little program that tests the throughput of fetch_add
on an increasing number of processors in your systems and if you chose
it, it couts the throughput of compare_exchange_weak. On my Ryzen
Threadripper 3990X (Zen2) / Windows 10 (SMT disabled) the fetch_add
timings are linar with increasing number of threads and the compare
_exchange_weak-timings are linear in the beginning, but become expo-
nential at the end.
I'd like to see your results:
#include <iostream>
#include <cstring>
#include <atomic>
#include <charconv>
#include <thread>
#include <vector>
#include <semaphore>
#include <chrono>
#include <algorithm>
#include <functional>
using namespace std;
using namespace chrono;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
bool xchg = strcmp( argv[1], "xchg" ) == 0;
if( argc - xchg < 2 )
return EXIT_FAILURE;
auto parseValue = []( char const *str ) -> unsigned
{
unsigned value;
from_chars_result fcr = from_chars( str, str + strlen( str ), value );
if( fcr.ec != errc() || *fcr.ptr )
return -1;
return value;
};
unsigned fromThreads, toThreads;
if( argc - xchg == 2 )
if( (fromThreads = toThreads = parseValue( argv[1 + xchg] )) == -1 )
return EXIT_FAILURE;
else;
else
if( (fromThreads = parseValue( argv[1 + xchg] )) == -1 || (toThreads =
parseValue( argv[2 + xchg] )) == -1 )
return EXIT_FAILURE;
unsigned hc = thread::hardware_concurrency();
hc = hc ? hc : toThreads;
toThreads = toThreads <= hc ? toThreads : hc;
fromThreads = fromThreads <= hc ? fromThreads : hc;
if( fromThreads > toThreads )
swap( fromThreads, toThreads );
for( unsigned nThreads = fromThreads; nThreads <= toThreads; ++nThreads )
{
atomic_uint readyCountDown( nThreads );
binary_semaphore semReady( 0 );
counting_semaphore semRun( 0 );
atomic_uint synch( nThreads );
atomic_uint64_t aui64;
atomic_uint64_t nsSum( 0 );
auto theThread = [&]( function<void()> &addFn, size_t n )
{
if( readyCountDown.fetch_sub( 1, memory_order_relaxed ) == 1 )
semReady.release();
semRun.acquire();
if( synch.fetch_sub( 1, memory_order_relaxed ) != 1 )
while( synch.load( memory_order_relaxed ) );
auto start = high_resolution_clock::now();
for( ; n; --n )
addFn();
nsSum.fetch_add( (int64_t)duration_cast<nanoseconds>(
high_resolution_clock::now() - start ).count(), memory_order_relaxed );
};
vector<jthread> threads;
threads.reserve( nThreads );
static size_t const TURNS = 10'000'000;
auto fetchAddFn = [&]() { aui64.fetch_add( 1, memory_order_relaxed ); };
auto cmpXchgFn = [&]()
{
uint64_t ref = aui64.load( memory_order_relaxed );
while( !aui64.compare_exchange_weak( ref, ref + 1,
memory_order_relaxed ) );
};
function<void()> xchgFn;
if( !xchg )
xchgFn = bind( fetchAddFn );
else
xchgFn = bind( cmpXchgFn );
for( unsigned t = 0; t != nThreads; ++t )
threads.emplace_back( theThread, xchgFn ), TURNS );
semReady.acquire();
semRun.release( nThreads );
for( jthread &thr : threads )
thr.join();
double ns = (double)(int64_t)nsSum.load( memory_order_relaxed );
ns = ns / ((double)TURNS * (int)nThreads);
cout << ns << endl;
}
}
The timings are important for every kind of synchronization on your PC.
The programm can be called like that
./a.out <n-threads> - tests fetch_add witn n-threads
./a.out <from-threads> <to-threads> - tests fetch_add ranging from
from-threads to to-threads
./a.out xchg <n-threads> - tests compar_exchange_weak with
n-threads
./a.out xchg <from-threads> <to-threads> - tests compar_exchange_weak
ranging from-threads to
to-threads
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-12-05 19:56 +0000 |
| Message-ID | <87bl1uomgb.fsf@bsb.me.uk> |
| In reply to | #82547 |
Bonita Montero <Bonita.Montero@gmail.com> writes: > for( unsigned t = 0; t != nThreads; ++t ) > threads.emplace_back( theThread, xchgFn ), TURNS ); ? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-12-05 15:22 -0800 |
| Message-ID | <sojhju$udc$1@dont-email.me> |
| In reply to | #82548 |
On 12/5/2021 11:56 AM, Ben Bacarisse wrote: > Bonita Montero <Bonita.Montero@gmail.com> writes: > > >> for( unsigned t = 0; t != nThreads; ++t ) >> threads.emplace_back( theThread, xchgFn ), TURNS ); > > ? > It seems way to complicated. To test fetch_add vs compare_exchange just: spawn T_N threads. each thread performs N fetch_add operations on a global counter. join the threads. Give a time. vs. spawn T_N threads. each thread performs N compare_exchange operations that increments a global counter. Basically using CAS to build a fetch_add. join the threads. Give a time. In my experience fetch_add always beats a CAS-loop on x86.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-12-05 23:43 +0000 |
| Message-ID | <875ys2obws.fsf@bsb.me.uk> |
| In reply to | #82550 |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes: > On 12/5/2021 11:56 AM, Ben Bacarisse wrote: >> Bonita Montero <Bonita.Montero@gmail.com> writes: >> >>> for( unsigned t = 0; t != nThreads; ++t ) >>> threads.emplace_back( theThread, xchgFn ), TURNS ); >> ? > > It seems way to complicated. In case it was not clear, my comment was about the syntax error. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-12-05 19:31 -0800 |
| Message-ID | <sok060$fb4$2@dont-email.me> |
| In reply to | #82551 |
On 12/5/2021 3:43 PM, Ben Bacarisse wrote: > "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes: > >> On 12/5/2021 11:56 AM, Ben Bacarisse wrote: >>> Bonita Montero <Bonita.Montero@gmail.com> writes: >>> >>>> for( unsigned t = 0; t != nThreads; ++t ) >>>> threads.emplace_back( theThread, xchgFn ), TURNS ); >>> ? >> >> It seems way to complicated. > > In case it was not clear, my comment was about the syntax error. > Oh ouch! I did not even notice it. You must be referencing this: threads.emplace_back( theThread, xchgFn ), TURNS ); The parenthesis balance.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-06 06:26 +0100 |
| Message-ID | <sok6up$d1b$2@dont-email.me> |
| In reply to | #82550 |
Am 06.12.2021 um 00:22 schrieb Chris M. Thomasson: > It seems way to complicated. To test fetch_add vs compare_exchange just: There's nothing complicated with my test. > In my experience fetch_add always beats a CAS-loop on x86. Of course, because it neer fails.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-06 06:24 +0100 |
| Message-ID | <sok6rb$d1b$1@dont-email.me> |
| In reply to | #82548 |
Am 05.12.2021 um 20:56 schrieb Ben Bacarisse: > Bonita Montero <Bonita.Montero@gmail.com> writes: > > >> for( unsigned t = 0; t != nThreads; ++t ) >> threads.emplace_back( theThread, xchgFn ), TURNS ); > > ? Remove one ).
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-12-06 10:45 +0000 |
| Message-ID | <87tufmm2qb.fsf@bsb.me.uk> |
| In reply to | #82554 |
Bonita Montero <Bonita.Montero@gmail.com> writes: > Am 05.12.2021 um 20:56 schrieb Ben Bacarisse: >> Bonita Montero <Bonita.Montero@gmail.com> writes: >> >>> for( unsigned t = 0; t != nThreads; ++t ) >>> threads.emplace_back( theThread, xchgFn ), TURNS ); >> ? > > Remove one ). The code does not compile with any of the three )s removed. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-06 13:09 +0100 |
| Message-ID | <sokuhp$pu4$1@dont-email.me> |
| In reply to | #82557 |
Am 06.12.2021 um 11:45 schrieb Ben Bacarisse: > Bonita Montero <Bonita.Montero@gmail.com> writes: > >> Am 05.12.2021 um 20:56 schrieb Ben Bacarisse: >>> Bonita Montero <Bonita.Montero@gmail.com> writes: >>> >>>> for( unsigned t = 0; t != nThreads; ++t ) >>>> threads.emplace_back( theThread, xchgFn ), TURNS ); >>> ? >> >> Remove one ). > > The code does not compile with any of the three )s removed. Take the latest code I've posted.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-06 06:27 +0100 |
| Message-ID | <sok70o$d1b$3@dont-email.me> |
| In reply to | #82547 |
So, here's the corrected version (C++20):
#include <iostream>
#include <cstring>
#include <atomic>
#include <charconv>
#include <thread>
#include <vector>
#include <semaphore>
#include <chrono>
#include <algorithm>
#include <functional>
using namespace std;
using namespace chrono;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
bool xchg = strcmp( argv[1], "xchg" ) == 0;
if( argc - xchg < 2 )
return EXIT_FAILURE;
auto parseValue = []( char const *str ) -> unsigned
{
unsigned value;
from_chars_result fcr = from_chars( str, str + strlen( str ), value );
if( fcr.ec != errc() || *fcr.ptr )
return -1;
return value;
};
unsigned fromThreads, toThreads;
if( argc - xchg == 2 )
if( (fromThreads = toThreads = parseValue( argv[1 + xchg] )) == -1 )
return EXIT_FAILURE;
else;
else
if( (fromThreads = parseValue( argv[1 + xchg] )) == -1 || (toThreads =
parseValue( argv[2 + xchg] )) == -1 )
return EXIT_FAILURE;
unsigned hc = thread::hardware_concurrency();
hc = hc ? hc : toThreads;
toThreads = toThreads <= hc ? toThreads : hc;
fromThreads = fromThreads <= hc ? fromThreads : hc;
if( fromThreads > toThreads )
swap( fromThreads, toThreads );
for( unsigned nThreads = fromThreads; nThreads <= toThreads; ++nThreads )
{
atomic_uint readyCountDown( nThreads );
binary_semaphore semReady( 0 );
counting_semaphore semRun( 0 );
atomic_uint synch( nThreads );
atomic_uint64_t aui64;
atomic_uint64_t nsSum( 0 );
auto theThread = [&]( function<void()> &addFn, size_t n )
{
if( readyCountDown.fetch_sub( 1, memory_order_relaxed ) == 1 )
semReady.release();
semRun.acquire();
if( synch.fetch_sub( 1, memory_order_relaxed ) != 1 )
while( synch.load( memory_order_relaxed ) );
auto start = high_resolution_clock::now();
for( ; n; addFn(), --n );
nsSum.fetch_add( (uint64_t)duration_cast<nanoseconds>(
high_resolution_clock::now() - start ).count(), memory_order_relaxed );
};
vector<jthread> threads;
threads.reserve( nThreads );
static size_t const TURNS = 10'000'000;
auto fetchAddFn = [&]() { aui64.fetch_add( 1, memory_order_relaxed ); };
auto cmpXchgFn = [&]()
{
uint64_t ref = aui64.load( memory_order_relaxed );
while( !aui64.compare_exchange_weak( ref, ref + 1,
memory_order_relaxed ) );
};
function<void()> xchgFn;
if( !xchg )
xchgFn = bind( fetchAddFn );
else
xchgFn = bind( cmpXchgFn );
for( unsigned t = 0; t != nThreads; ++t )
threads.emplace_back( theThread, ref( xchgFn ), TURNS );
semReady.acquire();
semRun.release( nThreads );
for( jthread &thr : threads )
thr.join();
double ns = (double)(int64_t)nsSum.load( memory_order_relaxed );
ns = ns / ((double)TURNS * (int)nThreads);
cout << nThreads << "\t" << ns << endl;
}
}
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-12-06 18:02 +0000 |
| Message-ID | <lfsrJ.116104$3q9.83106@fx47.iad> |
| In reply to | #82547 |
Bonita Montero <Bonita.Montero@gmail.com> writes: >I've written a little program that tests the throughput of fetch_add >on an increasing number of processors in your systems and if you chose This is _highly_ microarchitectural dependent. Some processors will acquire the cacheline into the nearest cache to ensure exclusive access for the add, while others will pass the entire operation to the last-level cache where it is executed atomically. In the former case, scaling will be very bad on large core counts. In the latter case, scaling will be quite good with large core counts, at least on a single-socket system. On a multi-socket system, this breaks down somewhat as the LLC on each socket will compete for the cache line. In any case, a couple dozen line assembler program would be a far better test than your overly complicated C++.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-07 06:27 +0100 |
| Message-ID | <somrba$tnk$1@dont-email.me> |
| In reply to | #82562 |
Am 06.12.2021 um 19:02 schrieb Scott Lurndal: > Some processors will acquire the cacheline into the nearest > cache to ensure exclusive access for the add, while > others will pass the entire operation to the last-level cache > where it is executed atomically. There's for sure no architecture that does atomic operations in the last level cache because this would be silly. > In any case, a couple dozen line assembler program would be a > far better test than your overly complicated C++. No, it wouldn't give better results and the code would be magnitudes longer if it would do the same.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-12-07 18:06 +0000 |
| Message-ID | <7pNrJ.79952$6a3.76905@fx41.iad> |
| In reply to | #82563 |
Bonita Montero <Bonita.Montero@gmail.com> writes: >Am 06.12.2021 um 19:02 schrieb Scott Lurndal: > >> Some processors will acquire the cacheline into the nearest >> cache to ensure exclusive access for the add, while >> others will pass the entire operation to the last-level cache >> where it is executed atomically. > >There's for sure no architecture that does atomic operations in >the last level cache because this would be silly. Well, are you sure? Why do you think it would be silly? https://genzconsortium.org/wp-content/uploads/2019/04/Gen-Z-Atomics-2019.pdf Given that at least three high-end processor chips have taped out just this year with the capability of executing "far" atomic operations in the LLC (or to a PCI Express Root complex host bridge), I think you really don't have a clue what you are talking about.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-07 19:14 +0100 |
| Message-ID | <soo8au$26q$1@dont-email.me> |
| In reply to | #82570 |
Am 07.12.2021 um 19:06 schrieb Scott Lurndal: > Bonita Montero <Bonita.Montero@gmail.com> writes: >> Am 06.12.2021 um 19:02 schrieb Scott Lurndal: >> >>> Some processors will acquire the cacheline into the nearest >>> cache to ensure exclusive access for the add, while >>> others will pass the entire operation to the last-level cache >>> where it is executed atomically. >> >> There's for sure no architecture that does atomic operations in >> the last level cache because this would be silly. > > Well, are you sure? Why do you think it would be silly? > > https://genzconsortium.org/wp-content/uploads/2019/04/Gen-Z-Atomics-2019.pdf > > Given that at least three high-end processor chips have taped out just > this year with the capability of executing "far" atomic operations in > the LLC (or to a PCI Express Root complex host bridge), I think you > really don't have a clue what you are talking about. And which CPUs currently support this Gen-Z interconnect ? And which CPUs currently use this far atomics for thread -synchronitation - none. Did you really read the paper and noted what Gen-Z is ? No.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-12-07 18:49 +0000 |
| Message-ID | <H0OrJ.110234$Z0a.15989@fx17.iad> |
| In reply to | #82573 |
Bonita Montero <Bonita.Montero@gmail.com> writes:
>Am 07.12.2021 um 19:06 schrieb Scott Lurndal:
>> Bonita Montero <Bonita.Montero@gmail.com> writes:
>>> Am 06.12.2021 um 19:02 schrieb Scott Lurndal:
>>>
>>>> Some processors will acquire the cacheline into the nearest
>>>> cache to ensure exclusive access for the add, while
>>>> others will pass the entire operation to the last-level cache
>>>> where it is executed atomically.
>>>
>>> There's for sure no architecture that does atomic operations in
>>> the last level cache because this would be silly.
>>
>> Well, are you sure? Why do you think it would be silly?
>>
>> https://genzconsortium.org/wp-content/uploads/2019/04/Gen-Z-Atomics-2019.pdf
>>
>> Given that at least three high-end processor chips have taped out just
>> this year with the capability of executing "far" atomic operations in
>> the LLC (or to a PCI Express Root complex host bridge), I think you
>> really don't have a clue what you are talking about.
>
>And which CPUs currently support this Gen-Z interconnect ?
I'd tell you, but various NDA's forbid.
>And which CPUs currently use this far atomics for thread
>-synchronitation - none.
How do you know? I'm aware of three. Two sampling to
customers, with core counts from 8 to 64. A handful of others
are in development by several processor vendors as I
write this.
>Did you really read the paper and noted what Gen-Z is ?
I know exactly what it is, and I know what CXL is as well,
both being part of my day job. And if you don't think Intel
is designing all of their server CPUs to be CXL [*] compatible,
you're not thinking.
[*] "In November 2021 the CXL Consortium and the GenZ Consortium
signed a letter of intent for Gen-Z to transfer its specifications
and assets to CXL, leaving CXL as the sole industry standard moving
forward"
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-07 19:54 +0100 |
| Message-ID | <sooam4$j94$1@dont-email.me> |
| In reply to | #82575 |
Am 07.12.2021 um 19:49 schrieb Scott Lurndal: > Bonita Montero <Bonita.Montero@gmail.com> writes: >> Am 07.12.2021 um 19:06 schrieb Scott Lurndal: >>> Bonita Montero <Bonita.Montero@gmail.com> writes: >>>> Am 06.12.2021 um 19:02 schrieb Scott Lurndal: >>>> >>>>> Some processors will acquire the cacheline into the nearest >>>>> cache to ensure exclusive access for the add, while >>>>> others will pass the entire operation to the last-level cache >>>>> where it is executed atomically. >>>> >>>> There's for sure no architecture that does atomic operations in >>>> the last level cache because this would be silly. >>> >>> Well, are you sure? Why do you think it would be silly? >>> >>> https://genzconsortium.org/wp-content/uploads/2019/04/Gen-Z-Atomics-2019.pdf >>> >>> Given that at least three high-end processor chips have taped out just >>> this year with the capability of executing "far" atomic operations in >>> the LLC (or to a PCI Express Root complex host bridge), I think you >>> really don't have a clue what you are talking about. >> >> And which CPUs currently support this Gen-Z interconnect ? > > I'd tell you, but various NDA's forbid. LOOOOOOOL. >> And which CPUs currently use this far atomics for thread >> -synchronitation - none. > How do you know? Because this would be slower since the lock-modifications woudln't be done in the L1-caches but in far memory. That's just a silly idea. > I'm aware of three. Two sampling to customers, with core > counts from 8 to 64. And you can't tell it because of NDAs. Hrhr.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-12-07 19:14 +0000 |
| Message-ID | <AoOrJ.102436$SW5.42759@fx45.iad> |
| In reply to | #82576 |
Bonita Montero <Bonita.Montero@gmail.com> writes: >Am 07.12.2021 um 19:49 schrieb Scott Lurndal: > >> How do you know? > >Because this would be slower since the lock-modifications >woudln't be done in the L1-caches but in far memory. That's >just a silly idea. Hello, it's a cache-coherent multiprocessor. You need to fetch it exclusively into the L1 first, so instead of sending the fetch (or invalidate if converting a shared line to owned), you send the atomic op and it gets handled atomically at the far end (e.g. LLC, PCI express device, SoC coprocessor) saving the interconnect (mesh, ring, whatever) bandwidth and the round-trip time between L1 and LLC and reducing contention for the line. If it's already in the L1 cache, then the processor will automatically treat it as a near-atomic, this is expected to be a rare case with correctly designed atomic usage.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-12-07 19:25 +0000 |
| Message-ID | <LyOrJ.56060$no7.16842@fx15.iad> |
| In reply to | #82579 |
scott@slp53.sl.home (Scott Lurndal) writes: >Bonita Montero <Bonita.Montero@gmail.com> writes: >>Am 07.12.2021 um 19:49 schrieb Scott Lurndal: > >> >>> How do you know? >> >>Because this would be slower since the lock-modifications >>woudln't be done in the L1-caches but in far memory. That's >>just a silly idea. > >Hello, it's a cache-coherent multiprocessor. You need to >fetch it exclusively into the L1 first, so instead of sending the fetch >(or invalidate if converting a shared line to owned), >you send the atomic op and it gets handled atomically at >the far end (e.g. LLC, PCI express device, SoC coprocessor) >saving the interconnect (mesh, ring, whatever) bandwidth and >the round-trip time between L1 and LLC and reducing contention >for the line. > >If it's already in the L1 cache, then the processor will >automatically treat it as a near-atomic, this is expected >to be a rare case with correctly designed atomic usage. In case you need a public reference for a shipping processor: https://developer.arm.com/documentation/102099/0000/L1-data-memory-system/Instruction-implementation-in-the-L1-data-memory-system
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-12-08 09:50 +0100 |
| Message-ID | <soprkm$64c$1@dont-email.me> |
| In reply to | #82580 |
Am 07.12.2021 um 20:25 schrieb Scott Lurndal: > scott@slp53.sl.home (Scott Lurndal) writes: >> Bonita Montero <Bonita.Montero@gmail.com> writes: >>> Am 07.12.2021 um 19:49 schrieb Scott Lurndal: >> >>> >>>> How do you know? >>> >>> Because this would be slower since the lock-modifications >>> woudln't be done in the L1-caches but in far memory. That's >>> just a silly idea. >> >> Hello, it's a cache-coherent multiprocessor. You need to >> fetch it exclusively into the L1 first, so instead of sending the fetch >> (or invalidate if converting a shared line to owned), >> you send the atomic op and it gets handled atomically at >> the far end (e.g. LLC, PCI express device, SoC coprocessor) >> saving the interconnect (mesh, ring, whatever) bandwidth and >> the round-trip time between L1 and LLC and reducing contention >> for the line. >> >> If it's already in the L1 cache, then the processor will >> automatically treat it as a near-atomic, this is expected >> to be a rare case with correctly designed atomic usage. > > In case you need a public reference for a shipping processor: > > https://developer.arm.com/documentation/102099/0000/L1-data-memory-system/Instruction-implementation-in-the-L1-data-memory-system That's not a processor implementing this Gen-Z interconnect and it's atomic facilities. This is just an optimization for a special kind of processor architecture.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-12-08 00:59 -0800 |
| Message-ID | <sops5m$8r4$2@dont-email.me> |
| In reply to | #82580 |
On 12/7/2021 11:25 AM, Scott Lurndal wrote: > scott@slp53.sl.home (Scott Lurndal) writes: >> Bonita Montero <Bonita.Montero@gmail.com> writes: >>> Am 07.12.2021 um 19:49 schrieb Scott Lurndal: >> >>> >>>> How do you know? >>> >>> Because this would be slower since the lock-modifications >>> woudln't be done in the L1-caches but in far memory. That's >>> just a silly idea. >> >> Hello, it's a cache-coherent multiprocessor. You need to >> fetch it exclusively into the L1 first, so instead of sending the fetch >> (or invalidate if converting a shared line to owned), >> you send the atomic op and it gets handled atomically at >> the far end (e.g. LLC, PCI express device, SoC coprocessor) >> saving the interconnect (mesh, ring, whatever) bandwidth and >> the round-trip time between L1 and LLC and reducing contention >> for the line. >> >> If it's already in the L1 cache, then the processor will >> automatically treat it as a near-atomic, this is expected >> to be a rare case with correctly designed atomic usage. > > In case you need a public reference for a shipping processor: > > https://developer.arm.com/documentation/102099/0000/L1-data-memory-system/Instruction-implementation-in-the-L1-data-memory-system > You have encountered the rabbit hole of Bonita! I have proved her/it wrong several times. No good, goes nowhere.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c++
csiph-web