Live data from Hacker News

A viable solution for Python concurrency

lwn.net

221–230 of 366 posts

Re: A viable solution for Python concurrency

#221
post #118

Earlier quoted context omitted.

Sometimes a project starts off aiming to solve a problem. maybe it's a data science problem, so support already exists in python so lets do that. Ok, it worked great and it's catching on with users. Now we need to scale, but we are running into concurrency issues. What is a better answer? Ok we will work on improving python concurrency under the hood, or completely scrap the code base and switch to a different langua…

I'll plead ignorance here: Do data science workflows often require high concurrency using a single interpreter? I thought all that stuff was compute-bound and parceled out to workers that farm out calculations to CPUs and GPUs.

Yes they do. I’ve written cython/numba as work arounds before. A lot of times if you need a small operation done many times the multiprocessor overhead is bad, but writing a pure python for loop over numpy/other tensors is awful for performance.

The answer historically has been c/c++ and bind to python. This work is mainly motivated by one of those libraries wanting to write less c++ bindings and be able to do operations like these parallel directly in python.

Re: A viable solution for Python concurrency

#222
post #218

Earlier quoted context omitted.

Yes, Swift uses refcounting.

Does Swift have a GIL? If not, how does it solve the problem of multithreaded reference counting?

Per earlier comment[1], Swift uses the biased refcounting approach Gross is proposing for Python.

[1]: https://news.ycombinator.com/item?id=28882299

Re: A viable solution for Python concurrency

#223

> With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast, non-atomic instructions. Any other thread accessing the object will use atomic operations on the shared reference count. > Whenever the owning th…

Threads don’t hold references - other objects do and we have to know how many do. If threads held a reference it might never be released. Since most objects are never shared we wouldn’t want to increment an atomic counter even once for those.

I think you have misunderstood GP. GP is trying to say, the thread that created the object has a remote (atomic) reference count of 1, in addition to a local reference count of 1. the remote reference count is simply initialized to be 1. During this initialization operation no atomic operation is used.

The only atomic operation is during destruction: the local reference count is decremented non-atomically, and then if it is zero, we need an atomic memory_order_release decrement for the remote reference count.

Re: A viable solution for Python concurrency

#224
post #208

Earlier quoted context omitted.

That's a fair opinion. Like many academics and data scientists are probably fine with Python as a tool for scripting or as a simple interface language for calling C libraries. But if Python continues as is, it will continue to to lose major enterprise traction as web companies transition to using faster languages for applications and infrastructure. It'll be tough to stave off the negative feedback loop at that point…

I'm not confident that's a bad thing, and I worry that we're judging languages on metrics that only make sense for startups. Does a language need to chase growth? I'm not saying Python shouldn't improve. But, if it comes to it, Python shouldn't cannibalize the niche it filled to do so. That will just spark other languages to fill the niche again.

> Python shouldn't cannibalize the niche it filled

It’s too late for that, IMO. Python’s already added async-await because it wants to be C#, type hints because it wants to be Java, and pattern matching because it wants to be Haskell.

People who liked Python because of what made it different from other languages have long since been left behind.

Re: A viable solution for Python concurrency

#225
Python3 would have been a great time to _also_ break the C interface in a way that would make multi-threading easier.

An opt-in for C libraries that are multi-threaded-aware could be useful as well. It would be a forcing function to ensure that libraries _eventually_ become MT-aware and eventually the older versions would drop away.

Re: A viable solution for Python concurrency

#226
This feels like Schrodinger's Cake to me (you know, having it and eating it too).

> ... the first of which is called "biased reference counts" ... With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast, non-atomic instructions. Any other thread accessing the object will use atomic operations on the shared reference count.

So if the owner needs to check the shared ref count every time it changes the count of the non-atomic local count, isn't that basically all the negatives of a single shared atomic counter?

Every design has pros and cons. Of course the GIL has well-known costs but it also has benefits. It makes developing C modules that integrate into Python relatively safe and trivial. And this is where Python shines: as plumbing where CPU intensive work (which is still single-threaded) is done by C modules. This is how the likes of Mercurial, Jupyter, numpy and scipy. And probably PyTorch but I know less about that.

My personal view is that the world has largely moved on from dynamically typed languages for anything non-trivial or that isn't essentially plumbing. For good reason. Of course people will bring up Javascript but it has a captive market as being the only thing that'll universally run code in a browser and the likes of TypeScript can ease that burden anyway.

This just feels fighting the seemingly inevitable fate of Python.

Re: A viable solution for Python concurrency

#227

Every time multithreading and the GIL comes up, I wonder why there are so many out there that are against multiprocess. In addition to solving the GIL problem by simply having multiple GILs, it also forces the designer to think properly about inter-thread data flow. Sure, it can never be quite as fast as true multithreading, but the results are probably more robust and as a bonus it doesn't break all the existing Pyt…

Multiprocess isn't a panacea. Several frameworks get grumpy depending on the order of forking. E.g. Iirc, try to use grpc to feed data to a process using pytorch dataloader, and it'll straight up crash. Huggingface is at least polite enough to warn you, but performance degrades.

Re: A viable solution for Python concurrency

#228
post #226

This feels like Schrodinger's Cake to me (you know, having it and eating it too). > ... the first of which is called "biased reference counts" ... With this scheme, the reference count in each object is split in two, with one "local" count for the owner (creator) of the object and a shared count for all other threads. Since the owner has exclusive access to its count, increments and decrements can be done with fast,…

The shared ref count is in the same cache line making the check basically free. Once you shift to shared then it is equivalent to the atomic shared ref count.

Re: A viable solution for Python concurrency

#229

Python3 would have been a great time to _also_ break the C interface in a way that would make multi-threading easier. An opt-in for C libraries that are multi-threaded-aware could be useful as well. It would be a forcing function to ensure that libraries _eventually_ become MT-aware and eventually the older versions would drop away.

Python 3.0 was released in 2008, over 13 years ago. We are almost certainly much closer to python 4.0 than to 3.0 today (given 3.10 RC is currently live)
Post reply on HN