redradist@gmail.com wrote:
On Mon, May 25, 2020 at 7:58 PM redradist@gmail.com wrote:
Edwin Zimmerman wrote: Only if your workload is CPU bound. Python optimizes IO bound workload performance by releasing the GIL while doing IO. Green threads generally do not offer this option. Real threads is not needed in Python: 1) Real threads do not work parallel They do when they do any sort of blocking operation. 2) Real threads only consume resources of OS 3) Real threads have also as trade off context switching between threads (small but ...) Not enough to be a concern. I think considering this trade offs we should switch Real Thread -> Green Thread internally or provide alternative functionality ... I think asyncio already provide functionality of GreenThread ... Okay maybe we should leave Real Threads as it is ... I need to think about it ... Yes, leave real threads as is, thanks. They're pretty important actually. If you don't want to use threads, that's fine, but don't change the threading module to not be threads. Not really a lot of point breaking backward compatibility for, uhh, zero gain. ChrisA I like the topic on https://www.reddit.com/r/Python/comments/bpp9hg/has_the_python_gil_been_slai... Answer written by CSI_Tech_Dept: ... What probably needs to be done is to have a compile option that causes Python to work without GIL but at the cost of breaking some of API (this would especially broke C API),
Chris Angelico wrote: then developers would have an option to chose:
compatibility with GIL
no GIL, full multithreading, but broken compatibility
If user could decide which python version to use and there was a clear benefit, existing applications would be migrated, people would also make sure their code works with both versions. ...
Interesting thoughts ...
Also I have tried to add in CPython adaptive reference counter ... What is it ... It is reference count that is based on knowledge that there are some some additional thread ... Take a look at this implementation: ``` inline void add_reference_couter(atomic_int * acnt) { if (num_other_threads > 0) { atomic_fetch_add_explicit(acnt, 1, memory_order_acq_rel); } else { ++(*acnt); } } inline void sub_reference_couter(atomic_int * acnt) { if (num_other_threads > 0) { atomic_fetch_sub_explicit(acnt, 1, memory_order_acq_rel); } else { --(*acnt); } } ``` Or implementation with complex RefCounter: ``` struct RefCounter { atomic_uint acnt; uint cnt; }; inline void add_reference_couter(RefCounter * ref_counter) { if (num_other_threads > 0) { atomic_fetch_add_explicit(&(*ref_counter).acnt, 1, memory_order_acq_rel); } else { ++(*ref_counter).cnt; } } inline void sub_reference_couter(RefCounter * ref_counter) { if (num_other_threads > 0) { atomic_fetch_sub_explicit(&(*ref_counter).acnt, 1, memory_order_acq_rel); } else { --(*ref_counter).cnt; if (0 == (*ref_counter).cnt) { atomic_fetch_sub_explicit(&(*ref_counter).acnt, 1, memory_order_acq_rel); } } } ``` I have also prepared test branch on my Ubuntu machine for this implementation ...