8 ms·
The GIL will never be removed from the main python implementation. Histortically, the main value of GIL removal proposals and implementations has been to spur
by dekhn 3y ago
The GIL will never be removed from the main python implementation. Histortically, the main value of GIL removal proposals and implementations has been to spur the core team to speed up single core codes.
I think it's too late to consider removing the gil from the main implementation. Like guido said in the PEP thread, the python core team burned the community for 10 years with the 2-3 switch, and a GIL change would be likely as impactful; we'd have 10 years of people complaining their stuff didn't work. Frankly I wish Guido would just come out and tell Sam "no, we can't put this in cpython. You did a great work but compatibility issues trump performance".
Kind of a shame because Hugunin implemented a Python on top of the CLR some 20 years ago and showed some extremely impressive performance results. Like jython, and pypy and other implementations, it never caught on because compatibility with cpython is one of the most important criteria for people dealing with lots of python code.
- giantrobot 3y ago> Like jython, and pypy and other implementations, it never caught on because compatibility with cpython is one of the most important criteria for people dealing with lots of python code. I think this is more an issue of popular packages were developed and tested against cpython and there wasn't enough effort available to port/test them against anything else. There's no special magic in cpython that Python programmers love, they just want their code to run. If they've got a numpy dependency (IIRC it doesn't support pypy but I'm not going to look it up so I may be corrected on that point this is a long parenthetical) they can't use an interpreter that doesn't support it. Even if it worked but had bugs it didn't have in cpython, they're still going to use cpython. Most people aren't writing Python for its super duper fast performance so they're fine leaving a little performance on the table by using the interpreter that their dependencies support. Whatever that is.
- dehrmann 3y agoJython doesn't have a good story for running native libraries like Numpy.
- giantrobot 3y agoSure, I didn't claim it did. My point is that Python programmers don't tend to have a particular fondness for an interpreter. They tend to care only about the ecosystem. If you came up with a cxpython interpreter that was faster than cpython and supported all the modules the same way (including C interop) Python programmers would jump over to it. If your cxpython was faster than cpython but didn't support everything they'd ignore it. Case in point: Python 2.7. While 3.x offered a lot of improvements it took years for some popular modules to support it. No one bothered to look twice at Python 3 until their dependencies supported it. Python programmers don't tend to care much about the interpreter so much as the code they wrote or use running correctly.
- fulafel 3y agoNumpy also wasn't very prominent in those days among Python users, the explosion of data science Python use happened later. (Actually NumPy didn't even exist for most of Jython's active development, but some of its predecessors did)
- coldtea 3y ago>the python core team burned the community for 10 years with the 2-3 switch, and a GIL change would be likely as impactfu A core team led by him, which also had the opportunity to make much more impactful changes during 3, including removing the GIL, since they were going to mess up compatibility anyway, but didn't. All that mess (and resulting split and multi-year slowdown in Py3 adoption) just to put in the utf-8 change and some trivial changes. It's only after 3.5 or so that 3 became interesting.
- paulddraper 3y agoIt's hard to argue that Python 3 should have been even less compatible.
- coldtea 3y agoIs it? It took the 5 year (at least) adoption hit anyway. How worse would it be if it had more features people want? I'd say it should have been less compatible when needed to add more substantial changes people wanted, as opposed to taking the hit for nothing! And it should be more compatible for things that were stupid decisions that had to eventually take back, like not having a bytes str solution.
- paulddraper 3y ago> How worse would it be 8 years or never
- misnome 3y ago> How worse would it be raku
- coldtea 3y agoRaku failed to timely deliver a stable release. And didn't stick to sensible new features, but tried to make an uber-language with everything plus the kitchen sink, and even a multi-language vm.
- jedberg 3y ago> The GIL will never be removed from the main python implementation. I don't see why. It's a much easier transition than 2 to 3. Make each package declare right at the top if they are non-GIL compatible. Have both modes available in the interpreter. If every piece of code imported has the declaration on top, then it runs in non-GIL mode, otherwise it runs in classic GIL mode. At first most code would still run in GIL mode, but over time most packages would be converted, especially if people stopped using packages that weren't compatible.
- powersnail 3y agoPython would be too dynamic a language to have non-GIL compatibility declared simply at top. Code can be imported/evaled/generated at runtime, and at any part of a script, which means that python would need to be able to switch from non-GIL to GIL at any time of execution.
- jedberg 3y agoIt's true that there are dynamic imports, but presumably it would be on the library maintainer to know about that, but also you could throw a catchable error about GIL imports or something like that. All I'm saying is that it's solvable, and more solvable than 2 to 3.
- samwillis 3y agoI completely agree, something like: from __future__ import multicore (The proposal seems to be to call it that rather than "no Gil" as it's more positive) And maybe if done in an __init__.py it applies to the whole module. Do that for v3.x then drop it completely for v4 I think the issue may be that maintaining both systems is too complex.
- richdougherty 3y agoI mean that seems horribly tricky, but also totally doable. Having read about JavaScript/Java VM optimisations in JITs and GC I would be surprised if a global state change like this is not manageable - think deoptimising the JS when you enter the debugger in the dev tools in your browser.
- Dork1234 3y agoI really think the GIL is saving a bunch of poorly written multi-threaded C++ wrappers/libraries out there. If they remove it, a bunch of bugs will appear in other libraries that might not be Pythons fault.
- eklitzke 3y agoThey're not "poorly written", the fact that you don't need to do any locking in C/C++ code is part of the existing Python API. Right now when Python code calls into C/C++ code the entire call is treated as if it's a single atomic bytecode instruction. Adding extra locking would just make the code slower and would accomplish absolutely nothing, which is why people don't do it.
- tinus_hn 3y agoThe interpreter could do locks around these calls automatically to make them atomic, while leaving itself multithreaded.
- KMag 3y agoIn order for the call into C to appear atomic to a multithreaded interpreter, all threads in the interpreter would need to be blocked during the call. That's possible to do, but you've just re-introduced the GIL whenever any thread is within a C extension. In the unlocked case, one could use low-overhead tricks used for GC safepoints in some interpreters. One low-overhead technique is a dedicated memory page from which a single byte is read at the beginning at of every opcode dispatch, and you mark that page non-readable when you need to freeze all the threads executing in the interpreter. You'd then have the SIGSEGV handler block each faulting thread until the one thread returned from C. That's fairly heavy in the case it's used, but pretty light-weight if not used.
- enedil 3y agoNevertheless, this is still a concern to wider ecosystem, if Python libraries suddenly start to break due to underlying issues. I don't think this can be neglected.
- zackees 3y agoI agree with this take. The GIL is hiding all kinds of concurrency bugs. If the CPython team default disable it then all hell is going to break loose. It's better to carve out special concurrency constructs for those that need it.
- nomel 3y agoNot sure why this was flagged dead. If you look at many stackoverflow answers, around threading, many explicitly rely on the GIL, quoting source/documentation “proving” that it’s safe, avoiding the use of threading.Lock() and the like. As an early python programmer, I copy pasted these types of answers. My old threaded code absolutely has these bugs. I’ve even seen code in production that has these bugs, because they’re sometimes dumb performance enhancements, rather than bugs, unless you happen to use a Python interpreter without a GIL, especially one that that doesn’t exist yet. Great care would have to be taken to make sure the GIL was not disabled by default, for anything an existing thread touches (or some super, dynamic aware, smarts to know if it can be disabled).
- tomn 3y agoI believe that GIL-removal projects aim to preserve this behaviour: https://peps.python.org/pep-0703/#container-thread-safety https://peps.python.org/pep-0703/#container-thread-safety That's why gilectomy carries an unreasonable single-threaded performance cost: many operations now need to take a lock where before they relied on the GIL.
- School-Cotton 3y agoWhy do you consider code that relies on the GIL to be buggy? Isn't the GIL a documented, stable part of Python? (Hence why it will probably never be removed).
- nomel 3y ago5th sentence in my comment: > I’ve even seen code in production that has these bugs, because they’re sometimes dumb performance enhancements, rather than bugs, unless you happen to use a Python interpreter without a GIL, especially one that that doesn’t exist yet.
- lacker 3y agoI think it's too late to consider removing the gil from the main implementation. I think it'll happen one day. Is Python going anywhere? Give it 20 years. The 2 -> 3 switch will be like the Y2K bug, only remembered by the oldest programmers. The memories of pain will fade, leaving only entertaining war stories. The GIL will still be there, and still be annoying. Then, when everyone has forgotten, the community will be ready. For an incredibly long and grinding transition to Python 4.
- ActorNightly 3y agoIn 20 years, you wouldn't have Python 4. You will have something like ChatGPT that you interact with and it writes code for you, down to the machine level instructions that are all hyperoptimized. Coding will be half typing, half verbal.
- jwandborg 3y agoImagine debugging hyperoptimized machine code. - Or would you just blame yourself for not stating your natural language instructions clearly enough and start over? I guess all of these complex problems would somehow be solved for everyone within the next 21 years and 364 days.
- ActorNightly 3y agoYou wouldn't debug it directly. The interaction will be something like telling the compiler to run the program for a certain input, and seeing wrong output, and then saying, "Hey, it should produce this output instead". The algorithm will be smart enough to simply regenerate the code minimally to produce the correct output.
- ilc 3y agoI think you have described a new definition of hell.
- 3y ago
- londons_explore 3y ago> compatibility issues trump performance". Surely it would be possible to drop back to GIL mode if any c extension is loaded which is incompatible with running lockless? Then you usually get speed, yet still maintain compatibility.
- mlyle 3y ago> if any c extension is loaded which is incompatible with running lockless? It'd be slightly magical to do. You'd probably have a giant RWLock, which is used for checking whether you're in the "lock free" mode. But at least almost all code could hit it only for read, and it could go away one day.
- takeda 3y agoI wouldn't say that GIL will never be removed, but I believe the GIL cannot be removed without breaking a lot of existing code. That means there could be another drama with migrations if that would be done. I think the most likely way they can effectively eliminate GIL would be to provide a compile option that would basically say "this enables paralellization, but your code is bo longer allowed to do A, B, C (there probably would be a lot more things)" People who want to get it would then adapt their code, and there could be pressure for other packages to make them work in that mode.
- godelski 3y ago> Histortically, the main value of GIL removal proposals and implementations has been to spur the core team to speed up single core codes. While I'm all for increasing single threaded performance[side rant] is this really a good argument? My understanding is that Moore's Law only currently exists because of the existence of more cores. Clock frequency has stagnated since 2004[0]. I mean feature size (Moore's Law) still exists[1] but IPS/core seems significantly flatter than IPS[2]. Aren't most of our performance gains from mutlicore? And as we push more in this direction (e.g. GPU taking over compute) doesn't this make this even worse for python? (Yes I understand that you can make C/CUDA calls but doesn't the GIL make problems here as well as prevent a native python solution?) [side rant] Still frustrated by things like that difference in speeds between math.sqrt(2.) (~0.002s/10k), np.sqrt(2.) (~0.010/10k), torch.sqrt(torch.tensor([2.])) (~0.039/10k). I know there's more going on in capabilities, but it is of course frustrating by the large differences. [0] http://cpudb.stanford.edu/visualize/clock_frequency http://cpudb.stanford.edu/visualize/clock_frequency [1] http://cpudb.stanford.edu/visualize/technology_scaling http://cpudb.stanford.edu/visualize/technology_scaling [2] https://en.wikipedia.org/wiki/Instructions_per_second#Millions_of_instructions_per_second_(MIPS) https://en.wikipedia.org/wiki/Instructions_per_second#Millio...
- aragilar 3y agoThat difference (at least in the math->numpy case) is entirely down to conversions (or at least it was when I profiled it ~7 years ago). If you're careful with types (i.e. avoiding converting from float to numpy scalar values), then the difference disappears.