4 ms·
From the article: "The only downsides of this approach are that it means that CPU bound Python code can’t scale to multiple cores within a single machine using
by seunosewa 14y ago
From the article: "The only downsides of this approach are that it means that CPU bound Python code can’t scale to multiple cores within a single machine using threads, and that IO operations can incur unexpected additional latency in the presence of a CPU bound thread."
Response: The only downside? As a Python user suffering from JVM envy, I have to say that that's a SERIOUS downside!
Here's why:
(1) Python is slow. Almost any real life program in pure Python will have CPU-bound components. (example: BBCode parsing on my forum).
(2) Most programs that need to scale won't need to scale beyond a single machine (the most active web forum on my continent runs on a single quad core server)
Therefore the need to be able to scale CPU-bound python programs to multiple cores on is a very real need. Even though we accept that removing the GIL is hard, let's not insult real-life Python users by suggesting that their needs are not real.
- hynek 14y agoThe article doesn’t say multi-CPU scaling isn’t necessary. It says that threads are usually the wrong answer anyway. There are great process based ways to scale out – look no further than Erlang to see it’s true.
- seunosewa 14y agoI use Python for my day job. I've experimented extensively with Java and Scala. I must say this: Threads are AWESOME. Threading is the most flexible model of concurrency because you can can build programs that EFFICIENTLY implement "alternative concurrency models" like message parsing and STM with threads. Threading is supported natively by every OS. And fast. Erlang is hyped as the ideal model for concurrency, but in practice is a niche product that's primarily useful for programs that are almost pure IO - chat servers, routing components like proxy servers and packet switches. The Erlang model does NOT apply to python, anyway, since Python processes are nothing like Erlang processes. Unlike Erlang processes, Python processes are very heavyweight and message passing between them is costly.
- hynek 14y agoIf you’re using python, the performance gap between processes with message passing and threads with locking is the last of your problems, believe me. The big difference is that processes are much more robust and testable. The cases where threads are really needed are fringe cases and – while it’s a pity – Python doesn’t seem the right language if you don’t want to go the Jython/IronPython way. The bigger problem is that people are used to go for threads by default although only few are able to write bug-free threaded code. It’s obsolete but prevalent performance wisdom and the fact that threads were really popular in the Java world.
- ak217 14y agoThis is a really short-sighted perspective. Proper support of threading inherently allows more performance and flexibility than multiprocessing. On top of them, you can build powerful, Pythonic abstractions like concurrent.futures.ThreadPoolExecutor.map and STM, and on top of those, even more powerful abstractions that help the developer avoid concurrency bugs. I'm really excited for PyPy. That is a project full of people who are not afraid to quickly iterate on powerful ideas that can make Python a high performance language that it deserves to be, instead of resorting to calling MT programming a "fringe case" and ad hominem attacks.
- hynek 14y agoI wish you’d read the article before making your accusations.
- ak217 14y agoI have. There's an ad hominem attack in the middle of it. Otherwise it's a great article. I understand that everyone here is acting in good faith and wants Python to be better, and the article otherwise contains lots of great information presented in a reasonable manner. You bring up lots of good points too. But other statements like the ones I mentioned are overly broad or brash.
- MetaCosm 14y agoSMP Erlang DOES use threads, it then uses green-processes and a custom scheduler to schedule processes fairly and preemptively across those threads. It doesn't use like 1 thread per process, but threads are a key component of how it works. It is absolutely nothing like spawning OS level processes. They are micro-processes, green-processes than live inside the Erlang VM.
- lrem 14y agoYeah, but do most programs that need to scale also need shared context? Otherwise, what are the big downsides of processes vs threads?
- seunosewa 14y agoMany programs can benefit from shared context. You can push all the shared context to your database, but it's often helpful to keep around some shared data structures for performance reasons. For example, you can cache pure Python functions using functools.lrucache, and share such caches between threads, but such caches can't be shared between processes. In-process data structures like dicts and lists are much, much faster than alternatives like memcached and redis because they avoid the overhead of IPC and deserialization, and they are also easier to use since they are built-in.
- slurgfest 14y agodicts and lists are fast, but that doesn't mean a threading approach which must protect your dicts and lists with various kinds of locking will be that fast, because your program will now be waiting on locks. What are you trying to do with memcached that it is not fast enough?
- seunosewa 14y ago> What are you trying to do with memcached that it is not fast enough? Fine-grained caching of objects that correspond to DB rows. Most pages touch hundreds of DB rows, due to the various relationships between objects. With memcached, you have to cache at a higher granularity and contort your code quite a bit to reduce the number of gets per request. > dicts and lists are fast, but ... your program will now be waiting on locks In my experience, the overhead of locking is often negligible. In Java-land, you can have millions of lock operations per second. IPC involves serialization, deserialization, and context switching, in addition to actual work. Most IPC routines are built on locks, anyway.
- slurgfest 14y ago
- slurgfest 14y agoYou are writing a forum which includes BBcode parsing, and Python's CPU usage is your bottleneck? Really? You are devoting multiple cores to parsing an individual user's BBcode? This is your example of a real need to remove the GIL?
- seunosewa 14y agoNo, that was just an example of a unexpectedly CPU-bound operation. My point was that you can't assume your Python program is not CPU-bound. Every time you have to do something non-trivial in Python, performance could become an issue.
- pwang 14y agoHow do you know it's not memory I/O bandwidth bound? Just curious.
- scott_s 14y agoFrom the perspective of a Python program, being memory bandwidth bound is the same as being CPU bound: you have the GIL, your process is in the running state in the OS, and is currently executing on a core. (I assume you mean truly mean bandwidth between main memory and the processor, and not to disk.)