- 944 FPS - 1 Update
- Recursive spinlock - 24 Updates
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: May 12 12:42PM -0700 On 5/11/2020 2:36 PM, Mr Flibble wrote: >> Can you see this animation on your end? It should get 60 fps... > I have very little free time these days even during the COVID-19 > lockdown (which doesn't really change things for a programmer). :D Indeed! :^) Afaict, ShaderToy tries to throttle everything down to 60 fps. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 06:53AM +0200 > Kaz Kylheku who originally invented that PTHREAD_MUTEX_ADAPTIVE_NP has > said that it has spin count adjusted by such estimator. Why should > he lie? Give the sourcecode as well as a benchmark. And Windows does it with a fixed spin-count. If this should work my benchmark should do the same given appropriate paramters. So compile my benchmark, experiment with different parameters and give a proof. I'll bet there will be no proof from you. |
"Öö Tiib" <ootiib@hot.ee>: May 11 11:43PM -0700 On Tuesday, 12 May 2020 07:54:06 UTC+3, Bonita Montero wrote: > benchmark should do the same given appropriate paramters. So compile > my benchmark, experiment with different parameters and give a proof. > I'll bet there will be no proof from you. Huh? You already *lost* your bet. Kaz Kylheku is simply super without any doubt. Linux is open source, glibc is open source and PTHREAD_MUTEX_ADAPTIVE_NP is fastest there for most things. Observe internet. It is full of examples. My first query to google reveals Firefox guys observing how performance was 480% times worse on OS-X two years ago and emulated happily Kaz code of glibc there to fix it. Problem solved. https://bugzilla.mozilla.org/show_bug.cgi?id=1457882 So ... who is stupid: spin locks or Bonita? It is because most critical sections in sane software are short. Few cycles: Lock, move unique_pointer of your job results into shared container, unlock. Another few cycles: Lock, take your next job from queue, unlock. Now work hard on your new job in isolation without any concurrency. However when there is aggressive contention to that shared container then hundreds of cycles into kernel call of blocking the thread start suddenly to frequent without spin locks and *bang* performance degrades into awful. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 08:49AM +0200 > Huh? You already *lost* your bet. Kaz Kylheku is simply super > without any doubt. Linux is open source, glibc is open source > and PTHREAD_MUTEX_ADAPTIVE_NP is fastest there for most things. Write a benchmark. Or look at Windows. Windows has a fixed spin-count. My benchmark does the same and counts the number of successful and unsuccessful spins. Please compile it and give me parameters that prove these stupid ideas. That's the latest code: #define _CRT_SECURE_NO_WARNINGS #include <Windows.h> #include <iostream> #include <cstdint> #include <cstdlib> #include <vector> #include <thread> #include <random> #include <atomic> #include <csignal> #pragma warning(disable: 6031) #pragma warning(disable: 6387) #pragma warning(disable: 26495) using namespace std; struct SpinMutex { SpinMutex( uint32_t spinCount ); void lock(); void unlock(); uint64_t getAndResetSpinSuceeds(); uint64_t getAndResetSpinFails(); private: uint32_t spinCount; atomic<uint32_t> lockCounter; HANDLE hEvent; static atomic<uint64_t> spinSucceeds, spinFails; uint64_t getAndZero( atomic<uint64_t> &value ); }; atomic<uint64_t> SpinMutex::spinSucceeds = 0; atomic<uint64_t> SpinMutex::spinFails = 0; SpinMutex::SpinMutex( uint32_t spinCount ) : spinCount( spinCount ), lockCounter( 0 ), hEvent( CreateEvent( nullptr, false, false, nullptr ) ) { } void SpinMutex::lock() { for( uint32_t sc = spinCount; sc; --sc ) { uint32_t cmp = 0; if( lockCounter.compare_exchange_weak( cmp, 1, memory_order_acquire, memory_order_relaxed ) ) { if( --sc ) // only count if it is not the first attempt to lock the mutex spinSucceeds.fetch_add( 1, memory_order_relaxed ); return; } } if( spinCount ) // only count fails if there's a spin-count spinFails.fetch_add( 1, memory_order_relaxed ); if( lockCounter.fetch_add( 1, memory_order_acquire ) != 0 ) WaitForSingleObject( hEvent, INFINITE ); } void SpinMutex::unlock() { if( lockCounter.fetch_sub( 1, memory_order_release ) != 1 ) SetEvent( hEvent ); } inline uint64_t SpinMutex::getAndResetSpinSuceeds() { return getAndZero( spinSucceeds ); } inline uint64_t SpinMutex::getAndResetSpinFails() { return getAndZero( spinFails ); } inline uint64_t SpinMutex::getAndZero( atomic<uint64_t> &value ) { uint64_t ref = value; while( !value.compare_exchange_weak( ref, 0 ) ); return ref; } void spendCycles( uint64_t cycles ); atomic<bool> stop; HANDLE hEvtStop; int main( int argc, char **argv ) { char const *errStr = "1. number of threads, 2. min non locked cycles, 3. max non locked cycles, 4. min locked cycles, 5. max locked cycles, 6. spin-count"; if( argc < 7 ) { cout << errStr << endl; return EXIT_FAILURE; } unsigned nThreads; unsigned long long minNonLockedCycles, maxNonLockedCycles; unsigned long long minLockedCycles, maxLockedCycles; unsigned spinCount; sscanf( argv[1], "%u", &nThreads ); sscanf( argv[2], "%llu", &minNonLockedCycles ); sscanf( argv[3], "%llu", &maxNonLockedCycles ); sscanf( argv[4], "%llu", &minLockedCycles ); sscanf( argv[5], "%llu", &maxLockedCycles ); sscanf( argv[6], "%u", &spinCount ); if( nThreads == 0 || minNonLockedCycles > maxNonLockedCycles || minLockedCycles > maxLockedCycles ) { cout << errStr << endl; return EXIT_FAILURE; } auto sigHandler = []( int sig ) -> void { ::stop = true; SetEvent( ::hEvtStop ); signal( SIGINT, SIG_IGN ); }; ::stop = false; ::hEvtStop = CreateEvent( nullptr, FALSE, FALSE, nullptr ); signal( SIGINT, sigHandler ); SpinMutex sm( spinCount ); auto thr = [&]() { random_device rd; minstd_rand mr( rd() ); uniform_int_distribution<uint64_t> uidNonLocked( minNonLockedCycles, maxNonLockedCycles ); uniform_int_distribution<uint64_t> uidLocked( minLockedCycles, maxLockedCycles ); while( !stop.load( memory_order_relaxed ) ) spendCycles( uidNonLocked( mr ) ), sm.lock(), spendCycles( uidLocked( mr ) ), sm.unlock(); }; vector<thread> threads; for( unsigned t = 0; t != nThreads; ++t ) threads.emplace_back( thr ); while( !stop.load( memory_order_relaxed ) ) if( WaitForSingleObject( ::hEvtStop, 1000 ) == WAIT_TIMEOUT ) { cout << "succeeds: " << sm.getAndResetSpinSuceeds() << endl; cout << "fails: " << sm.getAndResetSpinFails() << endl; } for( thread &t : threads ) t.join(); } PUBLIC ?spendCycles@@YAX_K@Z _TEXT SEGMENT ?spendCycles@@YAX_K@Z PROC test rcx, rcx jz byebye cycleLoop: dec rcx ; roughly one jump per clock-cycle jnz cycleLoop ; because there's only one branch-unit byebye: ret ?spendCycles@@YAX_K@Z ENDP _TEXT ENDS END I removed the random-table and changed to LCG-random-numbers for the non-locked-interval as well for the locked-interval. So give me the six parameters that prove what you said. > https://bugzilla.mozilla.org/show_bug.cgi?id=1457882 That's not the proof that I asked for. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 08:51AM +0200 So you can download the MSVC-2019-project here: https://fil.email/ffP0ghTV Compile it and give me the parameters that prove your assumptions. |
Ian Collins <ian-news@hotmail.com>: May 12 06:53PM +1200 On 12/05/2020 18:43, Öö Tiib wrote: > any doubt. Linux is open source, glibc is open source and > PTHREAD_MUTEX_ADAPTIVE_NP is fastest there for most things. > Observe internet. https://stackoverflow.com/questions/19863734/what-is-pthread-mutex-adaptive-np The top reply is from Kaz. -- Ian. |
"Öö Tiib" <ootiib@hot.ee>: May 11 11:59PM -0700 On Tuesday, 12 May 2020 09:49:46 UTC+3, Bonita Montero wrote: > > without any doubt. Linux is open source, glibc is open source > > and PTHREAD_MUTEX_ADAPTIVE_NP is fastest there for most things. > Write a benchmark. Why should I waste time to write a benchmark for checking that earth is round? > Or look at Windows. Windows is closed source garbage. Microsoft is awful, look what they did with Skype. It was great, but now Zoom beats it anytime in all aspects. > > https://bugzilla.mozilla.org/show_bug.cgi?id=1457882 > That's not the proof that I asked for. Sure you did not ask for proof that Bonita is stupid, and not spin locks ... but these are the only proofs there are to find. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 09:03AM +0200 > Windows is closed source garbage. Microsoft is awful, look what they > did with Skype. It was great, but now Zoom beats it anytime in all > aspects. My code does the same Windows does and it is not closed-souce. And some other implementations also have a fixed spin-count. |
"Öö Tiib" <ootiib@hot.ee>: May 12 12:56AM -0700 On Tuesday, 12 May 2020 10:03:38 UTC+3, Bonita Montero wrote: > > did with Skype. It was great, but now Zoom beats it anytime in all > > aspects. > My code does the same Windows does and it is not closed-souce. Chris M. Thomasson gave you advice "Please implement your code using a race detector, it will find your bugs. Try Relacy..." No one will look into that straw man code before you have fixed it. > And some other implementations also have a fixed spin-count. How does it matter? In our industry the real thing, the best of the breed is against what we should compare. Rest of "implementations" are performance issues to work around: https://bugzilla.mozilla.org/show_bug.cgi?id=1457882 |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 09:58AM +0200 > Chris M. Thomasson gave you advice "Please implement your code > using a race detector, it will find your bugs. Try Relacy..." Races are absolutely legal in this situation and, if your theory is right, should be prevented by an appropriate spin-count. And don't believe what Chris says; he is an underskilled developer with a lot of ideas which are not thought to the end. |
"Öö Tiib" <ootiib@hot.ee>: May 12 03:21AM -0700 On Tuesday, 12 May 2020 10:58:30 UTC+3, Bonita Montero wrote: > is right, should be prevented by an appropriate spin-count. > And don't believe what Chris says; he is an underskilled developer > with a lot of ideas which are not thought to the end. Races are undefined behavior in every code however low, and so if your straw man mutex allows races then it is worthless to compile. Chris is far more skilled than you. Most of work of every good program is embarrassingly parallel. The shared resources are used for to synchronize effort between threads. Bigger shared resources are protected with locks; smaller by having atomic access. Accesses of shared resources are designed to be quick in scalable architectures for not to make other threads to wait. Now lets look at your "skilled" benchmark. It is simulation of bogus design that does not scale anyway. The threads are doomed to drowse after one that sits and burns random amount of cycles in critical section. What is the difference how lot of cores we have, threads we make or what locks we use when the architecture of it is defective? |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 12:44PM +0200 > Races are undefined behavior in every code however low, and so if > your straw man mutex allows races then it is worthless to compile. No, the race here determines which thread can aquire the lock. Race-conditions don't directly lead to invalid code with lockfree code and in code which realises locks. In these cases race-con- ditions determine how is the first to acuire a lock or to update the data in a lockfree strucure. Every mutex depends on race-con- ditions! > Chris is far more skilled than you. Lol. > Now lets look at your "skilled" benchmark. > It is simulation of bogus design that does not scale anyway. It scales depending on the parameters you give. And having a lower and upper bound for the random values for the locking-interval as well for the unlocked interval is absolutely realistic. > The threads are doomed to drowse after one that sits and burns > random amount of cycles in critical section. That's realistic. The time spent in a critical section isn't usually constant. You can set a lower and upper bound for this time > What is the difference how lot of cores we have, threads we make > or what locks we use when the architecture of it is defective? I think it's worthless to ask for the correct parameters as you even don't understand the code. You're a underskilled developer also. As you don't understand that usual mutexes have race-con- ditions every discussion with you is a waste of time. |
"Öö Tiib" <ootiib@hot.ee>: May 12 04:25AM -0700 On Tuesday, 12 May 2020 13:45:07 UTC+3, Bonita Montero wrote: > ditions determine how is the first to acuire a lock or to update > the data in a lockfree strucure. Every mutex depends on race-con- > ditions! More nonsense. Mutexes and lock free schemas can be made using implementation specific atomic accesses and memory barriers but not with race conditions. And you clearly use standard atomics there. If your garbage allows race conditions then it is undefined behavior and labeling it as "mutex" or "lock free" does grant no privileges. > > or what locks we use when the architecture of it is defective? > I think it's worthless to ask for the correct parameters as you > even don't understand the code. I won't sure compile it. It is some kind of newbie crap with non-static getters for static members. You really refuse to test it claiming like you did there implement mutexes using memory fences and volatiles and so tools show false positives? > You're a underskilled developer > also. As you don't understand that usual mutexes have race-con- > ditions every discussion with you is a waste of time. Fine with me. Talk to mirror. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 01:32PM +0200 > implementation specific atomic accesses and memory barriers but > not with race conditions. And you clearly use standard atomics > there. A race-condition is when the data being modified by multiple threads is dependent on the timely order of the threads. The shared data of two threads trying to acquire a mutex is the lock-counter. And how this is modified depends on how the acesses are timed. So mutexes (and lockfeee data-structures) are an exception from the rule that race-conditions are always errors. > I won't sure compile it. It is some kind of newbie crap with > non-static getters for static members. I know that but that doesn't matter here. What matters is that is sufficient to prove what you said - if it could be proved. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 01:58PM +0200 > I won't sure compile it. It is some kind of newbie crap with > non-static getters for static members. ... The both counters need to be non-static, not the accessors static. But that has nothing to do with if the code is suitable to proof something you assume. |
"Öö Tiib" <ootiib@hot.ee>: May 12 05:10AM -0700 On Tuesday, 12 May 2020 14:32:29 UTC+3, Bonita Montero wrote: > this is modified depends on how the acesses are timed. So mutexes > (and lockfeee data-structures) are an exception from the rule that > race-conditions are always errors. That is not what standard says. Standard defines race like that: "The execution of a program contains a /data race/ if it contains two potentially concurrent conflicting actions, at least one of which is not atomic, and neither happens before the other, except for the special case for signal handlers described below. Any such data race results in undefined behavior." |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 02:17PM +0200 > not atomic, and neither happens before the other, except for the > special case for signal handlers described below. Any such data > race results in undefined behavior." The C-standard isn't defining what we're talking about here. The Wikipedia should be more definitive. |
"Öö Tiib" <ootiib@hot.ee>: May 12 05:31AM -0700 On Tuesday, 12 May 2020 15:17:42 UTC+3, Bonita Montero wrote: > > race results in undefined behavior." > The C-standard isn't defining what we're talking about here. > The Wikipedia should be more definitive. It is C++17 standard and we were talking about your C++ code in comp.lang.c++ so why Wikipedia's matters? Ironically Wikipedia quotes same what I did verbatim: https://en.wikipedia.org/wiki/Race_condition#Example_definitions_of_data_races_in_particular_concurrency_models |
"Öö Tiib" <ootiib@hot.ee>: May 12 06:34AM -0700 On Tuesday, 12 May 2020 14:58:10 UTC+3, Bonita Montero wrote: > The both counters need to be non-static, not the accessors static. > But that has nothing to do with if the code is suitable to proof > something you assume. How should anyone know if you wanted static or non-static members when you wrote static? No one can know what you wanted to write. Non-static accessories of static members is lousy. Lousiness indicates that it was shallowly considered. Too casual code usually contains serious logic errors too. About buggy software however no one cares how fast it behaves incorrectly and gives bogus answers. So test it yourself. Or go join "Genial" "poetical" "philosopher" of "scalable" and "lock free" stuff in comp.programming if you think that skill comes from nonsense posted not hard work done. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 04:12PM +0200 > It is C++17 standard and we were talking about your C++ code in > comp.lang.c++ so why Wikipedia's matters? You are pettifogging. My definition applies to every language. Think my implmenation would be written in any other language. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 04:14PM +0200 > How should anyone know if you wanted static or non-static members > when you wrote static? You said that the accessors need to be static so you alleged to know it. > usually contains serious logic errors too. About buggy software > however no one cares how fast it behaves incorrectly and gives > bogus answers. So test it yourself. My code does everything what it is needed to prove what you assume - if it can be proven. So give me the numbers ! |
"Öö Tiib" <ootiib@hot.ee>: May 12 08:11AM -0700 On Tuesday, 12 May 2020 17:12:20 UTC+3, Bonita Montero wrote: > > comp.lang.c++ so why Wikipedia's matters? > You are pettifogging. My definition applies to every language. > Think my implmenation would be written in any other language. It is you who are wiggling away from testing. I do not care. Test that your mutex does not contain data races what C++ standard defines to be undefined behavior and then test that using your mutex the more strict race like your Wikipedia defines can be avoided. Otherwise it is just random code not worth to compile. |
"Öö Tiib" <ootiib@hot.ee>: May 12 08:17AM -0700 On Tuesday, 12 May 2020 17:14:22 UTC+3, Bonita Montero wrote: > > when you wrote static? > You said that the accessors need to be static so you alleged > to know it. You lie. I wrote: "It is some kind of newbie crap with non-static getters for static members." It does say nothing what you try to misrepresent me claiming. |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 05:38PM +0200 > It is you who are wiggling away from testing. I give you the code, you shoud prove what you say if you know what you're talking about; but you don't- > do not care. Test that your mutex does not contain data races what C++ > standard defines to be undefined behavior ... Aside from the getter-issue and that the mutex doesn't handle resource -errors the code is correct. That you think that there are races which make it not appropriate for the issue we're talking about again shows that you're an underskilled "developer. > Otherwise it is just random code not worth to compile. You're not able to understand it. Aside from the issues above every mutex with a static spin-count is structured like mine. I said that data-races are absolutely normal for how mutexes work, you didn't understood why I said this and took this as a bug as you lack the simplest knowledge about how a mutex works. And when we're talking about the data-races beyond the usual working of a mutex but with spinning: these are also absolutely intended and not a bug (aside that spinning doesn't make sense). |
Bonita Montero <Bonita.Montero@gmail.com>: May 12 05:40PM +0200 > You lie. I wrote: "It is some kind of newbie crap with > non-static getters for static members." It does say > nothing what you try to misrepresent me claiming. Now you're trying to whitewash yourself. The above exactly means what I said. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment