SlideShare a Scribd company logo
1 of 62
Download to read offline
Understanding the
                                    Python GIL
                                                       David Beazley
                                                  http://www.dabeaz.com

                                                    Presented at PyCon 2010
                                                        Atlanta, Georgia

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                      1
Introduction
                • As a few of you might know, C Python has a
                        Global Interpreter Lock (GIL)
                        >>> import that
                        The Unwritten Rules of Python

                        1. You do not talk about the GIL.
                        2. You do NOT talk about the GIL.
                        3. Don't even mention the GIL. No seriously.
                        ...

                • It limits thread performance
                • Thus, a source of occasional "contention"
Copyright (C) 2010, David Beazley, http://www.dabeaz.com               2
An Experiment
                 • Consider this trivial CPU-bound function
                         def countdown(n):
                             while n > 0:
                                 n -= 1


                  • Run it once with a lot of work
                           COUNT = 100000000               # 100 million
                           countdown(COUNT)


                  • Now, subdivide the work across two threads
                          t1 = Thread(target=countdown,args=(COUNT//2,))
                          t2 = Thread(target=countdown,args=(COUNT//2,))
                          t1.start(); t2.start()
                          t1.join(); t2.join()



Copyright (C) 2010, David Beazley, http://www.dabeaz.com                   3
A Mystery
              • Performance on a quad-core MacPro
                              Sequential           : 7.8s
                              Threaded (2 threads) : 15.4s (2X slower!)

               • Performance if work divided across 4 threads
                              Threaded (4 threads) : 15.7s (about the same)

                • Performance if all but one CPU is disabled
                               Threaded (2 threads) : 11.3s (~35% faster than running
                               Threaded (4 threads) : 11.6s        with all 4 cores)

                • Think about it...
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                4
This Talk

                   • An in-depth look at threads and the GIL that
                          will explain that mystery and much more
                   • Some cool pictures
                   • A look at the new GIL in Python 3.2


Copyright (C) 2010, David Beazley, http://www.dabeaz.com               5
Disclaimers

                   • I gave an earlier talk on this topic at the
                          Chicago Python Users Group (chipy)
                            http://www.dabeaz.com/python/GIL.pdf

                    • That is a different, but related talk
                    • I'm going to go pretty fast... please hang on

Copyright (C) 2010, David Beazley, http://www.dabeaz.com              6
Part I
                                                      Threads and the GIL




Copyright (C) 2010, David Beazley, http://www.dabeaz.com                    7
Python Threads

               • Python threads are real system threads
                  • POSIX threads (pthreads)
                  • Windows threads
               • Fully managed by the host operating system
               • Represent threaded execution of the Python
                       interpreter process (written in C)


Copyright (C) 2010, David Beazley, http://www.dabeaz.com      8
Alas, the GIL

                   • Parallel execution is forbidden
                   • There is a "global interpreter lock"
                   • The GIL ensures that only one thread runs in
                           the interpreter at once
                   • Simplifies many low-level details (memory
                           management, callouts to C extensions, etc.)


Copyright (C) 2010, David Beazley, http://www.dabeaz.com                 9
Thread Execution Model
                • With the GIL, you get cooperative multitasking
                                                   I/O            I/O I/O      I/O     I/O
               Thread 1
                                         run                               run

               Thread 2                                    run
                                                                     run             run
               Thread 3
                                     release acquire         release acquire
                                       GIL     GIL             GIL     GIL

                • When a thread is running, it holds the GIL
                • GIL released on I/O (read,write,send,recv,etc.)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                     10
CPU Bound Tasks
              • CPU-bound threads that never perform I/O
                      are handled as a special case
              • A "check" occurs every 100 "ticks"
                                                                  k             k            k
                                                                ec            ec           ec
                                                             ch            ch            ch
                     CPU Bound
                       Thread                      Run 100       Run 100       Run 100
                                                    ticks         ticks         ticks



              • Change it using sys.setcheckinterval()
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                         11
What is a "Tick?"
       • Ticks loosely map to interpreter instructions
                                                                    >>> import dis
          def countdown(n):                                         >>> dis.dis(countdown)
              while n > 0:                                          0 SETUP_LOOP             33 (to 36)
                  print n                                           3 LOAD_FAST               0 (n)
                  n -= 1                                            6 LOAD_CONST              1 (0)
                                                                    9 COMPARE_OP              4 (>)

       •       Instructions in                             Tick 1   12 JUMP_IF_FALSE
                                                                    15 POP_TOP
                                                                                              19 (to 34)

               the Python VM                                        16 LOAD_FAST               0 (n)
                                                                    19 PRINT_ITEM

       • Not related to                                    Tick 2   20 PRINT_NEWLINE
                                                                    21 LOAD_FAST               0 (n)
               timing (ticks                               Tick 3   24 LOAD_CONST
                                                                    27 INPLACE_SUBTRACT
                                                                                               2 (1)

               might be long)                              Tick 4
                                                                    28 STORE_FAST              0 (n)
                                                                    31 JUMP_ABSOLUTE           3
                                                                    ...

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                               12
The Periodic "Check"
               • The periodic check is really simple
               • The currently running thread...
                    • Resets the tick counter
                    • Runs signal handlers if the main thread
                    • Releases the GIL
                    • Reacquires the GIL
               • That's it
Copyright (C) 2010, David Beazley, http://www.dabeaz.com        13
Implementation (C)
                                    /* Python/ceval.c */            Note: Each thread is
     Decrement                      ...
                                                                   running this same code
                                    if (--_Py_Ticker < 0) {
       ticks                            ...
      Reset ticks                       _Py_Ticker = _Py_CheckInterval;
                                        ...
                                        if (things_to_do) {
          Run                               if (Py_MakePendingCalls() < 0) {
         signal                                 ...
        handlers                            }
                                        }
                                        if (interpreter_lock) {
                                            /* Give another thread a chance */
                                            PyThread_release_lock(interpreter_lock);
     Release and
      reacquire                                        /* Other threads may run now */
       the GIL
                                                       PyThread_acquire_lock(interpreter_lock, 1);
                                             }
                                    ...
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                             14
Big Question

                • What is the source of that large CPU-bound
                       thread performance penalty?
                • There's just not much code to look at
                • Is GIL acquire/release solely responsible?
                • How would you find out?

Copyright (C) 2010, David Beazley, http://www.dabeaz.com          15
Part 2
                  The GIL and Thread Switching Deconstructed




Copyright (C) 2010, David Beazley, http://www.dabeaz.com            16
Python Locks
               • The Python interpreter only provides a single
                      lock type (in C) that is used to build all other
                      thread synchronization primitives
               • It's not a simple mutex lock
               • It's a binary semaphore constructed from a
                      pthreads mutex and a condition variable
               • The GIL is an instance of this lock
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                 17
Locks Deconstructed
                 • Locks consist of three parts
                            locked = 0                                      # Lock status
                            mutex = pthreads_mutex()                        # Lock for the status
                            cond   = pthreads_cond()                        # Used for waiting/wakeup


                  • Here's how acquire() and release() work
              release() {                                                    acquire() {
                  mutex.acquire()                                                mutex.acquire()
   pseudocode     locked = 0                                                     while (locked) {
                  mutex.release()                                                   cond.wait(mutex)
                  cond.signal()                                                  }
              }                                                                  locked = 1
                                                                                 mutex.release()
                                                                             }
                                                     A critical aspect
                                                  concerns this signaling
                                                    between threads
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                18
Thread Switching
                • Suppose you have two threads
                                                      Running
                         Thread 1




                         Thread 2                      READY




                • Thread 1 : Running
                • Thread 2 : Ready (Waiting for GIL)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com        19
Thread Switching
                • Easy case : Thread 1 performs I/O (read/write)
                                                                   I/O
                                                      Running
                          Thread 1
                                                             release
                                                               GIL




                         Thread 2                          READY




                • Thread 1 might block so it releases the GIL
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                 20
Thread Switching
                • Easy case : Thread 1 performs I/O (read/write)
                                                                    I/O
                                                      Running
                          Thread 1
                                                              release
                                                                      signal
                                                                GIL
                                                                pthreads/OS
                                                               context
                                                                switch
                                                                               Running
                         Thread 2                          READY

                                                                   acquire GIL


                • Release of GIL results in a signaling operation
                • Handled by thread library and operating system
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                 21
Thread Switching
                • Tricky case : Thread 1 runs until the check           ck
                                                                    che
                                                     100 ticks
                         Thread 1                                            ???
                                                             release
                                                                     signal
                                                               GIL
                                                              pthreads/OS
                                                                                   Which thread
                                                                                    runs now?

                         Thread 2                          READY             ???



           • Either thread is able to run
           • So, which is it?
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                          22
pthreads Undercover
               • Condition variables have an internal wait queue
                                                           Condition Variable
                                                          waiters
                                          cv.wait()            thread
                                                    enqueues
                                                                                       queue of
                                                                      thread
                                                                                        threads
                                                                      thread         waiting on cv
                                                                                     (often FIFO)
                                                                      thread

                                          cv.signal()                     dequeues


                • Signaling pops a thread off of the queue
                • However, what happens after that?
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                             23
OS Scheduling

                  • The operating system has a priority queue of
                         threads/processes ready to run
                  • Signaled threads simply enter that queue
                  • The operating system then runs the process
                         or thread with the highest priority
                  • It may or may not be the signaled thread

Copyright (C) 2010, David Beazley, http://www.dabeaz.com           24
Thread Switching
                • Thread 1 might keep going                               ck
                                                                      che
                                                     100 ticks                 Running
                       Thread 1
                    (high priority)                         release      acquire
                                                              GIL          GIL
                                                             pthreads/OS

                                                           schedule
                                                                                               Runs later
                       Thread 2                                  READY                   ...
                     (low priority)

           • Thread 2 moves to the OS "ready" queue and
                   executes at some later time
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                    25
Thread Switching
                • Thread 2 might immediately take over                   ck
                                                                     che
                                                     100 ticks
                        Thread 1
                     (low priority)                           release
                                                                      signal
                                                                GIL
                                                               pthreads/OS
                                                               context acquire
                                                                switch   GIL
                                                                             Running
                      Thread 2                             READY
                    (high priority)


           • Again, highest priority wins
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                               26
Part 3
                                                   What Can Go Wrong?




Copyright (C) 2010, David Beazley, http://www.dabeaz.com                27
GIL Instrumentation

            • To study thread scheduling in more detail, I
                    instrumented Python with some logging
            • Recorded a large trace of all GIL acquisitions,
                    releases, conflicts, retries, etc.
            • Goal was to get a better idea of how threads
                    were scheduled, interactions between threads,
                    internal GIL behavior, etc.


Copyright (C) 2010, David Beazley, http://www.dabeaz.com            28
GIL Logging
               • An extra tick counter was added to record
                       number of cycles of the check interval

               • Locks modified to log GIL events (pseudocode)
                         release() {                       acquire() {
                             mutex.acquire()                   mutex.acquire()
                             locked = 0                        if locked and gil:
                             if gil: log("RELEASE")               log("BUSY")
                             mutex.release()                   while locked:
                             cv.signal()                          cv.wait(mutex)
                         }                                        if locked and gil:
                                                                     log("RETRY")
              Note: Actual code in C, event                    locked = 1
               logs are stored entirely in                     if gil: log("ACQUIRE")
                                                               mutex.release()
               memory until exit (no I/O)                  }

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                29
A Sample Trace
   thread id                    t2     100      5351       ACQUIRE   ACQUIRE : GIL acquired
                                t2     100      5352       RELEASE
                                t2     100      5352       ACQUIRE   RELEASE : GIL released
                                t2     100      5353       RELEASE
                                t1     100      5353       ACQUIRE
      tick                      t2      38      5353       BUSY      BUSY : Attempted to acquire
                                t1     100      5354       RELEASE
   countdown                    t1     100      5354       ACQUIRE
                                                                     GIL, but it was already in use
                                t2      79      5354       RETRY
                                t1     100      5355       RELEASE
       total                    t1     100      5355       ACQUIRE
    number of                   t2      73      5355       RETRY      RETRY : Repeated attempt to
     "checks"                   t1     100      5356       RELEASE
                                                                      acquire the GIL, but it was
                                t2     100      5356       ACQUIRE
     executed                   t1      24      5356       BUSY       still in use
                                t2     100      5357       RELEASE



           • Trace files were large (>20MB for 1s of running)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                              30
Logging Results

                   • The logs were quite revealing
                   • Interesting behavior on one CPU
                   • Diabolical behavior on multiple CPUs
                   • Will briefly summarize findings followed by
                          an interactive visualization that shows details



Copyright (C) 2010, David Beazley, http://www.dabeaz.com                    31
Single CPU Threading
                • Threads alternate execution, but switch far
                       less frequently than you might imagine
                                                                  eck                    eck              ck
                                                               ch                     ch             c he
                                           100 ticks                  100 ticks
                    Thread 1                                                                   ...              READY

                                                      signal                 signal
                                                                                                      Thread
                                                                 pthreads/OS                          Context
                                                                                                       Switch

                                                      schedule
                                                                                                       run
                    Thread 2                                             READY



                • Hundreds to thousands of checks might occur
                       before a thread context switch (this is good)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                                32
Multicore GIL War
                • With multiple cores, runnable threads get
                       scheduled simultaneously (on different cores)
                       and battle over the GIL
                                Thread 1 (CPU 1)                    Thread 2 (CPU 2)
                                                   run
                            Release GIL                    signal
                            Acquire GIL                                      Wake
                                                   run
                                                                             Acquire GIL (fails)
                            Release GIL
                                                           signal
                            Acquire GIL
                                                                             Wake
                                                   run
                                                                             Acquire GIL (fails)


              • Thread 2 is repeatedly signaled, but when it
                      wakes up, the GIL is already gone (reacquired)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                           33
Multicore Event Handling
                • CPU-bound threads make GIL acquisition
                       difficult for threads that want to handle events
             Thread 1 (CPU 1)                                   Thread 2 (CPU 2)

                                                                        sleep
                                                       signal                    Event
                       run                                                Acquire GIL (fails)
                                                       signal
                                                                          Acquire GIL (fails)
                                                                                                     Might repeat
                                                       signal
                                                                                                  100s-1000s of times
                                                                          Acquire GIL (fails)
                                                       signal
                                                                          Acquire GIL (success)
                                                                         run


Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                           34
Behavior of I/O Handling
                • I/O ops often do not block
                                                                                   e
                                                                   ad rite rite rit rite
                                                                 re w w w w
                                                           run                         run
                                        Thread 1

                                                                   signal burst


                • Due to buffering, the OS is able to fulfill I/O
                        requests immediately and keep a thread running
                • However, the GIL is always released
                • Results in GIL thrashing under heavy load
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                     35
GIL Visualization (Demo)
              • Let's look at all of these effects
                                http://www.dabeaz.com/GIL
              • Some facts about the plots:
                 • Generated from ~2GB of log data
                 • Rendered into ~2 million PNG image tiles
                 • Created using custom scripts/tools
                 • I used the multiprocessing module
Copyright (C) 2010, David Beazley, http://www.dabeaz.com      36
Part 4
                                                           A Better GIL?




Copyright (C) 2010, David Beazley, http://www.dabeaz.com                   37
The New GIL
                 • Python 3.2 has a new GIL implementation
                         (only available by svn checkout)
                 • The work of Antoine Pitrou (applause)
                 • It aims to solve all that GIL thrashing
                 • It is the first major change to the GIL since
                         the inception of Python threads in 1992
                 • Let's go take a look
Copyright (C) 2010, David Beazley, http://www.dabeaz.com           38
New Thread Switching
                  • Instead of ticks, there is now a global variable
                           /* Python/ceval.c */
                           ...

                           static volatile int gil_drop_request = 0;



                  • A thread runs until the value gets set to 1
                  • At which point, the thread must drop the GIL
                  • Big question: How does that happen?
Copyright (C) 2010, David Beazley, http://www.dabeaz.com               39
New GIL Illustrated
                • Suppose that there is just one thread
                                          running
                 Thread 1


                • It just runs and runs and runs ...
                   • Never releases the GIL
                   • Never sends any signals
                   • Life is great!
Copyright (C) 2010, David Beazley, http://www.dabeaz.com   40
New GIL Illustrated
                • Suppose, a second thread appears
                                          running
                 Thread 1



                 Thread 2                         SUSPENDED




                • It is suspended because it doesn't have the GIL
                • Somehow, it has to get it from Thread 1
Copyright (C) 2010, David Beazley, http://www.dabeaz.com            41
New GIL Illustrated
                • Waiting thread does a timed cv_wait on GIL
                                          running
                 Thread 1


                                                               By default TIMEOUT
                 Thread 2                         SUSPENDED   is 5 milliseconds, but it
                                                                  can be changed
                          cv_wait(gil, TIMEOUT)



                • The idea : Thread 2 waits to see if the GIL gets
                       released voluntarily by Thread 1 (e.g., if there is
                       I/O or it goes to sleep for some reason)
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                  42
New GIL Illustrated
                • Voluntary GIL release
                                          running                   I/O
                 Thread 1
                                                           signal

                                                                          running
                 Thread 2                         SUSPENDED

                          cv_wait(gil, TIMEOUT)




                • This is the easy case. Second thread is signaled
                       and it grabs the GIL.

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                            43
New GIL Illustrated
                • If timeout, set gil_drop_request
                                          running
                 Thread 1
                                                   gil_drop_request = 1

                                                         TIMEOUT
                Thread 2                          SUSPENDED

                          cv_wait(gil, TIMEOUT)                           cv_wait(gil, TIMEOUT)




                • Thread 2 then repeats its wait on the GIL
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                          44
New GIL Illustrated
                • Thread 1 suspends after current instruction
                                          running
                 Thread 1
                                                   gil_drop_request = 1     signal

                                                         TIMEOUT                     running
                 Thread 2                         SUSPENDED

                          cv_wait(gil, TIMEOUT)                           cv_wait(gil, TIMEOUT)



              • Signal is sent to indicate release of GIL

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                          45
New GIL Illustrated
                • On a forced release, a thread waits for an ack
                                                                 cv_wait(gotgil)
                                          running
                 Thread 1                                                  WAIT

                                                   gil_drop_request = 1     signal    signal (ack)

                                                         TIMEOUT                     running
                 Thread 2                         SUSPENDED

                          cv_wait(gil, TIMEOUT)                           cv_wait(gil, TIMEOUT)



                • Ack ensures that the other thread successfully
                       got the GIL and is now running
                • This eliminates the "GIL Battle"                                                   46
Copyright (C) 2010, David Beazley, http://www.dabeaz.com
New GIL Illustrated
                • The process now repeats itself for Thread 1
                                                                 cv_wait(gotgil)       cv_wait(gil, TIMEOUT)
                                          running
                 Thread 1                                                  WAIT                SUSPENDED

                                                   gil_drop_request = 1     signal     gil_drop_request =0

                                                         TIMEOUT                     running
                 Thread 2                         SUSPENDED

                          cv_wait(gil, TIMEOUT)                           cv_wait(gil, TIMEOUT)



               • So, the timeout sequence happens over and
                      over again as CPU-bound threads execute

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                       47
Does it Work?
               • Yes, apparently (4-core MacPro, OS-X 10.6.2)
                                 Sequential           : 11.53s
                                 Threaded (2 threads) : 11.93s
                                 Threaded (4 threads) : 12.32s

                • Keep in mind, Python is still limited by the GIL
                        in all of the usual ways (threads still provide no
                        performance boost)
                • But, otherwise, it looks promising!
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                     48
Part 5
                                                           Die GIL Die!!!




Copyright (C) 2010, David Beazley, http://www.dabeaz.com                    49
Alas, It Doesn't Work
                • The New GIL impacts I/O performance
                • Here is a fragment of network code
                          Thread 1                         Thread 2
                          def spin():                      def echo_server(s):
                              while True:                      while True:
                                  # some work                      data = s.recv(8192)
                                  pass                             if not data:
                                                                       break
                                                                   s.sendall(data)


               • One thread is working (CPU-bound)
               • One thread receives and echos data on a socket
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                 50
Response Time
                • New GIL increases response time
                                                           running
                               Thread 1
                                                                          gil_drop_request = 1      signal

                                                                                      TIMEOUT           running
                              Thread 2                                         READY
                                                                        cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT)

                                                               data
                                                              arrives

                • To handle I/O, a thread must go through the
                       entire timeout sequence to get control
                • Ignores the high priority of I/O or events
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                              51
Unfair Wakeup/Starvation
                • Most deserving thread may not get the GIL
                                                    running
                           Thread 1
                                                                     gil_drop_request = 1   signal

                                                                              TIMEOUT
                           Thread 2                                    READY                 READY
                                                                cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT)
                                                            data
                                                           arrives
                                                                                                     running
                          Thread 3                                             READY

                                                                     wakeup

                 • Caused by internal condition variable queuing
                 • Further increases the response time
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                       52
Convoy Effect
           • I/O operations that don't block cause stalls
                                                  running
                         Thread 1
                                                                 timeout sig   timeout   sig   timeout
                         Thread 2                               READY          READY           READY


                                                                         send           send
                                                            data                      (executes
                                                                       (executes
                                                           arrives                   immediately)
                                                                      immediately)


           • Since I/O operations always release the GIL,
                   CPU-bound threads will always try to restart
           • On I/O completion (almost immediately), the
                   GIL is gone so the timeout has to repeat
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                                                 53
An Experiment
                • Send 10MB of data to an echo server thread
                       that's competing with a CPU-bound thread
                            Python 2.6.4 (2 CPU) : 0.57s (10 sample average)
                            Python 3.2 (2 CPU) : 12.4s (20x slower)

                • What if echo competes with 2 CPU threads?
                            Python 2.6.4 (2 CPU) : 0.25s (Better performance?)
                            Python 3.2 (2 CPU) : 46.9s (4x slower than before)
                            Python 3.2 (1 CPU) : 0.14s (330x faster than 2 cores?)

                • Arg!                 Enough already!

Copyright (C) 2010, David Beazley, http://www.dabeaz.com                             54
Part 6
                                               Score : Multicore 2, GIL 0




Copyright (C) 2010, David Beazley, http://www.dabeaz.com                    55
Fixing the GIL

                    • Can the GIL's erratic behavior be fixed?
                    • My opinion :Yes, maybe.
                    • The new GIL is already 90% there
                    • It just needs a few extra bits

Copyright (C) 2010, David Beazley, http://www.dabeaz.com        56
The Missing Bits

               • Priorities: There must be some way to separate
                      CPU-bound (low priority) and I/O bound (high
                      priority) threads
               • Preemption: High priority threads must be able
                      to immediately preempt low-priority threads




Copyright (C) 2010, David Beazley, http://www.dabeaz.com             57
A Possible Solution
            • Operating systems use timeouts to automatically
                    adjust task priorities (multilevel feedback queuing)
                        • If a thread is preempted by a timeout, it is
                               penalized with lowered priority (bad thread)
                        • If a thread suspends early, it is rewarded with
                               raised priority (good thread)
                        • High priority threads always preempt low
                               priority threads
            • Maybe it could be applied to the new GIL?
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                      58
Remove the GIL?

                • This entire talk has been about the problem of
                       implementing one tiny little itty bitty lock
                • Fixing Python to remove the GIL entirely is an
                       exponentially more difficult project
                • If there is one thing to take away, there are
                       practical reasons why the GIL remains


Copyright (C) 2010, David Beazley, http://www.dabeaz.com              59
Final Thoughts
               • Don't use this talk to justify not using threads
               • Threads are a very useful programming tool
                      for many kinds of concurrency problems
               • Threads can also offer excellent performance
                      even with the GIL (you need to study it)
               • However, you should know about the tricky
                      corner cases


Copyright (C) 2010, David Beazley, http://www.dabeaz.com            60
Final Thoughts
               • Improving the GIL is something that all
                      Python programmers should care about
               • Multicore is not going away
               • You might not use threads yourself, but they
                      are used for a variety of low-level purposes in
                      frameworks and libraries you might be using
               • More predictable thread behavior is good
Copyright (C) 2010, David Beazley, http://www.dabeaz.com                61
Thread Terminated

                             • That's it!
                             • Thanks for listening!
                             • Questions


Copyright (C) 2010, David Beazley, http://www.dabeaz.com   62

More Related Content

What's hot

COSCUP2016 - LLVM框架、由淺入淺
COSCUP2016 - LLVM框架、由淺入淺COSCUP2016 - LLVM框架、由淺入淺
COSCUP2016 - LLVM框架、由淺入淺hydai
 
Effective Testing with Ansible and InSpec
Effective Testing with Ansible and InSpecEffective Testing with Ansible and InSpec
Effective Testing with Ansible and InSpecNathen Harvey
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners HubSpot
 
Binderのはじめの一歩とAndroid
Binderのはじめの一歩とAndroidBinderのはじめの一歩とAndroid
Binderのはじめの一歩とAndroidl_b__
 
TensroFlow XLA : JIT編 (r1.3版)
TensroFlow XLA : JIT編 (r1.3版)TensroFlow XLA : JIT編 (r1.3版)
TensroFlow XLA : JIT編 (r1.3版)Mr. Vengineer
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
USENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsUSENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsBrendan Gregg
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 
[KubeCon NA 2020] containerd: Rootless Containers 2020
[KubeCon NA 2020] containerd: Rootless Containers 2020[KubeCon NA 2020] containerd: Rootless Containers 2020
[KubeCon NA 2020] containerd: Rootless Containers 2020Akihiro Suda
 
計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~Norishige Fukushima
 
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)NTT DATA Technology & Innovation
 
Linux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance ShowdownLinux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance ShowdownScyllaDB
 
Openwrt wireless
Openwrt wirelessOpenwrt wireless
Openwrt wireless晓东 杜
 
OS Process Synchronization, semaphore and Monitors
OS Process Synchronization, semaphore and MonitorsOS Process Synchronization, semaphore and Monitors
OS Process Synchronization, semaphore and Monitorssgpraju
 

What's hot (20)

COSCUP2016 - LLVM框架、由淺入淺
COSCUP2016 - LLVM框架、由淺入淺COSCUP2016 - LLVM框架、由淺入淺
COSCUP2016 - LLVM框架、由淺入淺
 
Effective Testing with Ansible and InSpec
Effective Testing with Ansible and InSpecEffective Testing with Ansible and InSpec
Effective Testing with Ansible and InSpec
 
File system implementation
File system implementationFile system implementation
File system implementation
 
Introduction to OpenMP
Introduction to OpenMPIntroduction to OpenMP
Introduction to OpenMP
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners
 
Binderのはじめの一歩とAndroid
Binderのはじめの一歩とAndroidBinderのはじめの一歩とAndroid
Binderのはじめの一歩とAndroid
 
TensroFlow XLA : JIT編 (r1.3版)
TensroFlow XLA : JIT編 (r1.3版)TensroFlow XLA : JIT編 (r1.3版)
TensroFlow XLA : JIT編 (r1.3版)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
USENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame GraphsUSENIX ATC 2017: Visualizing Performance with Flame Graphs
USENIX ATC 2017: Visualizing Performance with Flame Graphs
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
Intro to Git and GitHub
Intro to Git and GitHubIntro to Git and GitHub
Intro to Git and GitHub
 
Daemons
DaemonsDaemons
Daemons
 
Git commands
Git commandsGit commands
Git commands
 
Integrity Protection for Embedded Systems
Integrity Protection for Embedded SystemsIntegrity Protection for Embedded Systems
Integrity Protection for Embedded Systems
 
[KubeCon NA 2020] containerd: Rootless Containers 2020
[KubeCon NA 2020] containerd: Rootless Containers 2020[KubeCon NA 2020] containerd: Rootless Containers 2020
[KubeCon NA 2020] containerd: Rootless Containers 2020
 
計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~
 
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
 
Linux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance ShowdownLinux Kernel vs DPDK: HTTP Performance Showdown
Linux Kernel vs DPDK: HTTP Performance Showdown
 
Openwrt wireless
Openwrt wirelessOpenwrt wireless
Openwrt wireless
 
OS Process Synchronization, semaphore and Monitors
OS Process Synchronization, semaphore and MonitorsOS Process Synchronization, semaphore and Monitors
OS Process Synchronization, semaphore and Monitors
 

Viewers also liked

In Search of the Perfect Global Interpreter Lock
In Search of the Perfect Global Interpreter LockIn Search of the Perfect Global Interpreter Lock
In Search of the Perfect Global Interpreter LockDavid Beazley (Dabeaz LLC)
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...David Beazley (Dabeaz LLC)
 
Using Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard IIUsing Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard IIDavid Beazley (Dabeaz LLC)
 
Intelligent Thumbnail Selection
Intelligent Thumbnail SelectionIntelligent Thumbnail Selection
Intelligent Thumbnail SelectionKamil Sindi
 
Pycon11: Python threads: Dive into GIL!
Pycon11: Python threads: Dive into GIL!Pycon11: Python threads: Dive into GIL!
Pycon11: Python threads: Dive into GIL!Chetan Giridhar
 
Generator Tricks for Systems Programmers, v2.0
Generator Tricks for Systems Programmers, v2.0Generator Tricks for Systems Programmers, v2.0
Generator Tricks for Systems Programmers, v2.0David Beazley (Dabeaz LLC)
 
A Curious Course on Coroutines and Concurrency
A Curious Course on Coroutines and ConcurrencyA Curious Course on Coroutines and Concurrency
A Curious Course on Coroutines and ConcurrencyDavid Beazley (Dabeaz LLC)
 

Viewers also liked (17)

In Search of the Perfect Global Interpreter Lock
In Search of the Perfect Global Interpreter LockIn Search of the Perfect Global Interpreter Lock
In Search of the Perfect Global Interpreter Lock
 
Python in Action (Part 1)
Python in Action (Part 1)Python in Action (Part 1)
Python in Action (Part 1)
 
Generators: The Final Frontier
Generators: The Final FrontierGenerators: The Final Frontier
Generators: The Final Frontier
 
Python in Action (Part 2)
Python in Action (Part 2)Python in Action (Part 2)
Python in Action (Part 2)
 
Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
 
Writing Parsers and Compilers with PLY
Writing Parsers and Compilers with PLYWriting Parsers and Compilers with PLY
Writing Parsers and Compilers with PLY
 
Interfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIGInterfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIG
 
Using Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard IIUsing Python3 to Build a Cloud Computing Service for my Superboard II
Using Python3 to Build a Cloud Computing Service for my Superboard II
 
Mastering Python 3 I/O
Mastering Python 3 I/OMastering Python 3 I/O
Mastering Python 3 I/O
 
Python Generator Hacking
Python Generator HackingPython Generator Hacking
Python Generator Hacking
 
Generator Tricks for Systems Programmers
Generator Tricks for Systems ProgrammersGenerator Tricks for Systems Programmers
Generator Tricks for Systems Programmers
 
Intelligent Thumbnail Selection
Intelligent Thumbnail SelectionIntelligent Thumbnail Selection
Intelligent Thumbnail Selection
 
Pycon11: Python threads: Dive into GIL!
Pycon11: Python threads: Dive into GIL!Pycon11: Python threads: Dive into GIL!
Pycon11: Python threads: Dive into GIL!
 
Generator Tricks for Systems Programmers, v2.0
Generator Tricks for Systems Programmers, v2.0Generator Tricks for Systems Programmers, v2.0
Generator Tricks for Systems Programmers, v2.0
 
A Curious Course on Coroutines and Concurrency
A Curious Course on Coroutines and ConcurrencyA Curious Course on Coroutines and Concurrency
A Curious Course on Coroutines and Concurrency
 
An Introduction to Python Concurrency
An Introduction to Python ConcurrencyAn Introduction to Python Concurrency
An Introduction to Python Concurrency
 

Similar to Understanding the Python GIL

[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...Akihiro Suda
 
Scale11x lxc talk
Scale11x lxc talkScale11x lxc talk
Scale11x lxc talkdotCloud
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Felix Geisendörfer
 
[FOSDEM 2020] Lazy distribution of container images
[FOSDEM 2020] Lazy distribution of container images[FOSDEM 2020] Lazy distribution of container images
[FOSDEM 2020] Lazy distribution of container imagesAkihiro Suda
 
Python on a chip
Python on a chipPython on a chip
Python on a chipstoggi
 
January 2022: Central Iowa Linux Users Group: Git
January 2022: Central Iowa Linux Users Group: GitJanuary 2022: Central Iowa Linux Users Group: Git
January 2022: Central Iowa Linux Users Group: GitAndrew Denner
 
Pragmatic Smalltalk
Pragmatic SmalltalkPragmatic Smalltalk
Pragmatic SmalltalkESUG
 
Using IT Equipment in Live Broadcast
Using IT Equipment in Live BroadcastUsing IT Equipment in Live Broadcast
Using IT Equipment in Live BroadcastKieran Kunhya
 
Docker: do's and don'ts
Docker: do's and don'tsDocker: do's and don'ts
Docker: do's and don'tsPaolo Tonin
 
yocto_scale_handout-with-notes
yocto_scale_handout-with-notesyocto_scale_handout-with-notes
yocto_scale_handout-with-notesSteve Arnold
 
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...Jérôme Petazzoni
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPUTomer Gabel
 
WTF is Twisted?
WTF is Twisted?WTF is Twisted?
WTF is Twisted?hawkowl
 
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...npinto
 

Similar to Understanding the Python GIL (20)

How do event loops work in Python?
How do event loops work in Python?How do event loops work in Python?
How do event loops work in Python?
 
Guild Prototype
Guild PrototypeGuild Prototype
Guild Prototype
 
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
[Paris Container Day 2021] nerdctl: yet another Docker & Docker Compose imple...
 
Scale11x lxc talk
Scale11x lxc talkScale11x lxc talk
Scale11x lxc talk
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?
 
Bigdata roundtable-storm
Bigdata roundtable-stormBigdata roundtable-storm
Bigdata roundtable-storm
 
[FOSDEM 2020] Lazy distribution of container images
[FOSDEM 2020] Lazy distribution of container images[FOSDEM 2020] Lazy distribution of container images
[FOSDEM 2020] Lazy distribution of container images
 
Python on a chip
Python on a chipPython on a chip
Python on a chip
 
January 2022: Central Iowa Linux Users Group: Git
January 2022: Central Iowa Linux Users Group: GitJanuary 2022: Central Iowa Linux Users Group: Git
January 2022: Central Iowa Linux Users Group: Git
 
Pragmatic Smalltalk
Pragmatic SmalltalkPragmatic Smalltalk
Pragmatic Smalltalk
 
Using IT Equipment in Live Broadcast
Using IT Equipment in Live BroadcastUsing IT Equipment in Live Broadcast
Using IT Equipment in Live Broadcast
 
Git Presentation
Git PresentationGit Presentation
Git Presentation
 
Docker: do's and don'ts
Docker: do's and don'tsDocker: do's and don'ts
Docker: do's and don'ts
 
yocto_scale_handout-with-notes
yocto_scale_handout-with-notesyocto_scale_handout-with-notes
yocto_scale_handout-with-notes
 
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...
Docker 1 0 1 0 1: a Docker introduction, actualized for the stable release of...
 
How shit works: the CPU
How shit works: the CPUHow shit works: the CPU
How shit works: the CPU
 
WTF is Twisted?
WTF is Twisted?WTF is Twisted?
WTF is Twisted?
 
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...
IAP09 CUDA@MIT 6.963 - Lecture 01: GPU Computing using CUDA (David Luebke, NV...
 
Bento lunch talk
Bento   lunch talkBento   lunch talk
Bento lunch talk
 
Docker_AGH_v0.1.3
Docker_AGH_v0.1.3Docker_AGH_v0.1.3
Docker_AGH_v0.1.3
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 

Recently uploaded (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 

Understanding the Python GIL

  • 1. Understanding the Python GIL David Beazley http://www.dabeaz.com Presented at PyCon 2010 Atlanta, Georgia Copyright (C) 2010, David Beazley, http://www.dabeaz.com 1
  • 2. Introduction • As a few of you might know, C Python has a Global Interpreter Lock (GIL) >>> import that The Unwritten Rules of Python 1. You do not talk about the GIL. 2. You do NOT talk about the GIL. 3. Don't even mention the GIL. No seriously. ... • It limits thread performance • Thus, a source of occasional "contention" Copyright (C) 2010, David Beazley, http://www.dabeaz.com 2
  • 3. An Experiment • Consider this trivial CPU-bound function def countdown(n): while n > 0: n -= 1 • Run it once with a lot of work COUNT = 100000000 # 100 million countdown(COUNT) • Now, subdivide the work across two threads t1 = Thread(target=countdown,args=(COUNT//2,)) t2 = Thread(target=countdown,args=(COUNT//2,)) t1.start(); t2.start() t1.join(); t2.join() Copyright (C) 2010, David Beazley, http://www.dabeaz.com 3
  • 4. A Mystery • Performance on a quad-core MacPro Sequential : 7.8s Threaded (2 threads) : 15.4s (2X slower!) • Performance if work divided across 4 threads Threaded (4 threads) : 15.7s (about the same) • Performance if all but one CPU is disabled Threaded (2 threads) : 11.3s (~35% faster than running Threaded (4 threads) : 11.6s with all 4 cores) • Think about it... Copyright (C) 2010, David Beazley, http://www.dabeaz.com 4
  • 5. This Talk • An in-depth look at threads and the GIL that will explain that mystery and much more • Some cool pictures • A look at the new GIL in Python 3.2 Copyright (C) 2010, David Beazley, http://www.dabeaz.com 5
  • 6. Disclaimers • I gave an earlier talk on this topic at the Chicago Python Users Group (chipy) http://www.dabeaz.com/python/GIL.pdf • That is a different, but related talk • I'm going to go pretty fast... please hang on Copyright (C) 2010, David Beazley, http://www.dabeaz.com 6
  • 7. Part I Threads and the GIL Copyright (C) 2010, David Beazley, http://www.dabeaz.com 7
  • 8. Python Threads • Python threads are real system threads • POSIX threads (pthreads) • Windows threads • Fully managed by the host operating system • Represent threaded execution of the Python interpreter process (written in C) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 8
  • 9. Alas, the GIL • Parallel execution is forbidden • There is a "global interpreter lock" • The GIL ensures that only one thread runs in the interpreter at once • Simplifies many low-level details (memory management, callouts to C extensions, etc.) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 9
  • 10. Thread Execution Model • With the GIL, you get cooperative multitasking I/O I/O I/O I/O I/O Thread 1 run run Thread 2 run run run Thread 3 release acquire release acquire GIL GIL GIL GIL • When a thread is running, it holds the GIL • GIL released on I/O (read,write,send,recv,etc.) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 10
  • 11. CPU Bound Tasks • CPU-bound threads that never perform I/O are handled as a special case • A "check" occurs every 100 "ticks" k k k ec ec ec ch ch ch CPU Bound Thread Run 100 Run 100 Run 100 ticks ticks ticks • Change it using sys.setcheckinterval() Copyright (C) 2010, David Beazley, http://www.dabeaz.com 11
  • 12. What is a "Tick?" • Ticks loosely map to interpreter instructions >>> import dis def countdown(n): >>> dis.dis(countdown) while n > 0: 0 SETUP_LOOP 33 (to 36) print n 3 LOAD_FAST 0 (n) n -= 1 6 LOAD_CONST 1 (0) 9 COMPARE_OP 4 (>) • Instructions in Tick 1 12 JUMP_IF_FALSE 15 POP_TOP 19 (to 34) the Python VM 16 LOAD_FAST 0 (n) 19 PRINT_ITEM • Not related to Tick 2 20 PRINT_NEWLINE 21 LOAD_FAST 0 (n) timing (ticks Tick 3 24 LOAD_CONST 27 INPLACE_SUBTRACT 2 (1) might be long) Tick 4 28 STORE_FAST 0 (n) 31 JUMP_ABSOLUTE 3 ... Copyright (C) 2010, David Beazley, http://www.dabeaz.com 12
  • 13. The Periodic "Check" • The periodic check is really simple • The currently running thread... • Resets the tick counter • Runs signal handlers if the main thread • Releases the GIL • Reacquires the GIL • That's it Copyright (C) 2010, David Beazley, http://www.dabeaz.com 13
  • 14. Implementation (C) /* Python/ceval.c */ Note: Each thread is Decrement ... running this same code if (--_Py_Ticker < 0) { ticks ... Reset ticks _Py_Ticker = _Py_CheckInterval; ... if (things_to_do) { Run if (Py_MakePendingCalls() < 0) { signal ... handlers } } if (interpreter_lock) { /* Give another thread a chance */ PyThread_release_lock(interpreter_lock); Release and reacquire /* Other threads may run now */ the GIL PyThread_acquire_lock(interpreter_lock, 1); } ... Copyright (C) 2010, David Beazley, http://www.dabeaz.com 14
  • 15. Big Question • What is the source of that large CPU-bound thread performance penalty? • There's just not much code to look at • Is GIL acquire/release solely responsible? • How would you find out? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 15
  • 16. Part 2 The GIL and Thread Switching Deconstructed Copyright (C) 2010, David Beazley, http://www.dabeaz.com 16
  • 17. Python Locks • The Python interpreter only provides a single lock type (in C) that is used to build all other thread synchronization primitives • It's not a simple mutex lock • It's a binary semaphore constructed from a pthreads mutex and a condition variable • The GIL is an instance of this lock Copyright (C) 2010, David Beazley, http://www.dabeaz.com 17
  • 18. Locks Deconstructed • Locks consist of three parts locked = 0 # Lock status mutex = pthreads_mutex() # Lock for the status cond = pthreads_cond() # Used for waiting/wakeup • Here's how acquire() and release() work release() { acquire() { mutex.acquire() mutex.acquire() pseudocode locked = 0 while (locked) { mutex.release() cond.wait(mutex) cond.signal() } } locked = 1 mutex.release() } A critical aspect concerns this signaling between threads Copyright (C) 2010, David Beazley, http://www.dabeaz.com 18
  • 19. Thread Switching • Suppose you have two threads Running Thread 1 Thread 2 READY • Thread 1 : Running • Thread 2 : Ready (Waiting for GIL) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 19
  • 20. Thread Switching • Easy case : Thread 1 performs I/O (read/write) I/O Running Thread 1 release GIL Thread 2 READY • Thread 1 might block so it releases the GIL Copyright (C) 2010, David Beazley, http://www.dabeaz.com 20
  • 21. Thread Switching • Easy case : Thread 1 performs I/O (read/write) I/O Running Thread 1 release signal GIL pthreads/OS context switch Running Thread 2 READY acquire GIL • Release of GIL results in a signaling operation • Handled by thread library and operating system Copyright (C) 2010, David Beazley, http://www.dabeaz.com 21
  • 22. Thread Switching • Tricky case : Thread 1 runs until the check ck che 100 ticks Thread 1 ??? release signal GIL pthreads/OS Which thread runs now? Thread 2 READY ??? • Either thread is able to run • So, which is it? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 22
  • 23. pthreads Undercover • Condition variables have an internal wait queue Condition Variable waiters cv.wait() thread enqueues queue of thread threads thread waiting on cv (often FIFO) thread cv.signal() dequeues • Signaling pops a thread off of the queue • However, what happens after that? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 23
  • 24. OS Scheduling • The operating system has a priority queue of threads/processes ready to run • Signaled threads simply enter that queue • The operating system then runs the process or thread with the highest priority • It may or may not be the signaled thread Copyright (C) 2010, David Beazley, http://www.dabeaz.com 24
  • 25. Thread Switching • Thread 1 might keep going ck che 100 ticks Running Thread 1 (high priority) release acquire GIL GIL pthreads/OS schedule Runs later Thread 2 READY ... (low priority) • Thread 2 moves to the OS "ready" queue and executes at some later time Copyright (C) 2010, David Beazley, http://www.dabeaz.com 25
  • 26. Thread Switching • Thread 2 might immediately take over ck che 100 ticks Thread 1 (low priority) release signal GIL pthreads/OS context acquire switch GIL Running Thread 2 READY (high priority) • Again, highest priority wins Copyright (C) 2010, David Beazley, http://www.dabeaz.com 26
  • 27. Part 3 What Can Go Wrong? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 27
  • 28. GIL Instrumentation • To study thread scheduling in more detail, I instrumented Python with some logging • Recorded a large trace of all GIL acquisitions, releases, conflicts, retries, etc. • Goal was to get a better idea of how threads were scheduled, interactions between threads, internal GIL behavior, etc. Copyright (C) 2010, David Beazley, http://www.dabeaz.com 28
  • 29. GIL Logging • An extra tick counter was added to record number of cycles of the check interval • Locks modified to log GIL events (pseudocode) release() { acquire() { mutex.acquire() mutex.acquire() locked = 0 if locked and gil: if gil: log("RELEASE") log("BUSY") mutex.release() while locked: cv.signal() cv.wait(mutex) } if locked and gil: log("RETRY") Note: Actual code in C, event locked = 1 logs are stored entirely in if gil: log("ACQUIRE") mutex.release() memory until exit (no I/O) } Copyright (C) 2010, David Beazley, http://www.dabeaz.com 29
  • 30. A Sample Trace thread id t2 100 5351 ACQUIRE ACQUIRE : GIL acquired t2 100 5352 RELEASE t2 100 5352 ACQUIRE RELEASE : GIL released t2 100 5353 RELEASE t1 100 5353 ACQUIRE tick t2 38 5353 BUSY BUSY : Attempted to acquire t1 100 5354 RELEASE countdown t1 100 5354 ACQUIRE GIL, but it was already in use t2 79 5354 RETRY t1 100 5355 RELEASE total t1 100 5355 ACQUIRE number of t2 73 5355 RETRY RETRY : Repeated attempt to "checks" t1 100 5356 RELEASE acquire the GIL, but it was t2 100 5356 ACQUIRE executed t1 24 5356 BUSY still in use t2 100 5357 RELEASE • Trace files were large (>20MB for 1s of running) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 30
  • 31. Logging Results • The logs were quite revealing • Interesting behavior on one CPU • Diabolical behavior on multiple CPUs • Will briefly summarize findings followed by an interactive visualization that shows details Copyright (C) 2010, David Beazley, http://www.dabeaz.com 31
  • 32. Single CPU Threading • Threads alternate execution, but switch far less frequently than you might imagine eck eck ck ch ch c he 100 ticks 100 ticks Thread 1 ... READY signal signal Thread pthreads/OS Context Switch schedule run Thread 2 READY • Hundreds to thousands of checks might occur before a thread context switch (this is good) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 32
  • 33. Multicore GIL War • With multiple cores, runnable threads get scheduled simultaneously (on different cores) and battle over the GIL Thread 1 (CPU 1) Thread 2 (CPU 2) run Release GIL signal Acquire GIL Wake run Acquire GIL (fails) Release GIL signal Acquire GIL Wake run Acquire GIL (fails) • Thread 2 is repeatedly signaled, but when it wakes up, the GIL is already gone (reacquired) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 33
  • 34. Multicore Event Handling • CPU-bound threads make GIL acquisition difficult for threads that want to handle events Thread 1 (CPU 1) Thread 2 (CPU 2) sleep signal Event run Acquire GIL (fails) signal Acquire GIL (fails) Might repeat signal 100s-1000s of times Acquire GIL (fails) signal Acquire GIL (success) run Copyright (C) 2010, David Beazley, http://www.dabeaz.com 34
  • 35. Behavior of I/O Handling • I/O ops often do not block e ad rite rite rit rite re w w w w run run Thread 1 signal burst • Due to buffering, the OS is able to fulfill I/O requests immediately and keep a thread running • However, the GIL is always released • Results in GIL thrashing under heavy load Copyright (C) 2010, David Beazley, http://www.dabeaz.com 35
  • 36. GIL Visualization (Demo) • Let's look at all of these effects http://www.dabeaz.com/GIL • Some facts about the plots: • Generated from ~2GB of log data • Rendered into ~2 million PNG image tiles • Created using custom scripts/tools • I used the multiprocessing module Copyright (C) 2010, David Beazley, http://www.dabeaz.com 36
  • 37. Part 4 A Better GIL? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 37
  • 38. The New GIL • Python 3.2 has a new GIL implementation (only available by svn checkout) • The work of Antoine Pitrou (applause) • It aims to solve all that GIL thrashing • It is the first major change to the GIL since the inception of Python threads in 1992 • Let's go take a look Copyright (C) 2010, David Beazley, http://www.dabeaz.com 38
  • 39. New Thread Switching • Instead of ticks, there is now a global variable /* Python/ceval.c */ ... static volatile int gil_drop_request = 0; • A thread runs until the value gets set to 1 • At which point, the thread must drop the GIL • Big question: How does that happen? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 39
  • 40. New GIL Illustrated • Suppose that there is just one thread running Thread 1 • It just runs and runs and runs ... • Never releases the GIL • Never sends any signals • Life is great! Copyright (C) 2010, David Beazley, http://www.dabeaz.com 40
  • 41. New GIL Illustrated • Suppose, a second thread appears running Thread 1 Thread 2 SUSPENDED • It is suspended because it doesn't have the GIL • Somehow, it has to get it from Thread 1 Copyright (C) 2010, David Beazley, http://www.dabeaz.com 41
  • 42. New GIL Illustrated • Waiting thread does a timed cv_wait on GIL running Thread 1 By default TIMEOUT Thread 2 SUSPENDED is 5 milliseconds, but it can be changed cv_wait(gil, TIMEOUT) • The idea : Thread 2 waits to see if the GIL gets released voluntarily by Thread 1 (e.g., if there is I/O or it goes to sleep for some reason) Copyright (C) 2010, David Beazley, http://www.dabeaz.com 42
  • 43. New GIL Illustrated • Voluntary GIL release running I/O Thread 1 signal running Thread 2 SUSPENDED cv_wait(gil, TIMEOUT) • This is the easy case. Second thread is signaled and it grabs the GIL. Copyright (C) 2010, David Beazley, http://www.dabeaz.com 43
  • 44. New GIL Illustrated • If timeout, set gil_drop_request running Thread 1 gil_drop_request = 1 TIMEOUT Thread 2 SUSPENDED cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) • Thread 2 then repeats its wait on the GIL Copyright (C) 2010, David Beazley, http://www.dabeaz.com 44
  • 45. New GIL Illustrated • Thread 1 suspends after current instruction running Thread 1 gil_drop_request = 1 signal TIMEOUT running Thread 2 SUSPENDED cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) • Signal is sent to indicate release of GIL Copyright (C) 2010, David Beazley, http://www.dabeaz.com 45
  • 46. New GIL Illustrated • On a forced release, a thread waits for an ack cv_wait(gotgil) running Thread 1 WAIT gil_drop_request = 1 signal signal (ack) TIMEOUT running Thread 2 SUSPENDED cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) • Ack ensures that the other thread successfully got the GIL and is now running • This eliminates the "GIL Battle" 46 Copyright (C) 2010, David Beazley, http://www.dabeaz.com
  • 47. New GIL Illustrated • The process now repeats itself for Thread 1 cv_wait(gotgil) cv_wait(gil, TIMEOUT) running Thread 1 WAIT SUSPENDED gil_drop_request = 1 signal gil_drop_request =0 TIMEOUT running Thread 2 SUSPENDED cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) • So, the timeout sequence happens over and over again as CPU-bound threads execute Copyright (C) 2010, David Beazley, http://www.dabeaz.com 47
  • 48. Does it Work? • Yes, apparently (4-core MacPro, OS-X 10.6.2) Sequential : 11.53s Threaded (2 threads) : 11.93s Threaded (4 threads) : 12.32s • Keep in mind, Python is still limited by the GIL in all of the usual ways (threads still provide no performance boost) • But, otherwise, it looks promising! Copyright (C) 2010, David Beazley, http://www.dabeaz.com 48
  • 49. Part 5 Die GIL Die!!! Copyright (C) 2010, David Beazley, http://www.dabeaz.com 49
  • 50. Alas, It Doesn't Work • The New GIL impacts I/O performance • Here is a fragment of network code Thread 1 Thread 2 def spin(): def echo_server(s): while True: while True: # some work data = s.recv(8192) pass if not data: break s.sendall(data) • One thread is working (CPU-bound) • One thread receives and echos data on a socket Copyright (C) 2010, David Beazley, http://www.dabeaz.com 50
  • 51. Response Time • New GIL increases response time running Thread 1 gil_drop_request = 1 signal TIMEOUT running Thread 2 READY cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) data arrives • To handle I/O, a thread must go through the entire timeout sequence to get control • Ignores the high priority of I/O or events Copyright (C) 2010, David Beazley, http://www.dabeaz.com 51
  • 52. Unfair Wakeup/Starvation • Most deserving thread may not get the GIL running Thread 1 gil_drop_request = 1 signal TIMEOUT Thread 2 READY READY cv_wait(gil, TIMEOUT) cv_wait(gil, TIMEOUT) data arrives running Thread 3 READY wakeup • Caused by internal condition variable queuing • Further increases the response time Copyright (C) 2010, David Beazley, http://www.dabeaz.com 52
  • 53. Convoy Effect • I/O operations that don't block cause stalls running Thread 1 timeout sig timeout sig timeout Thread 2 READY READY READY send send data (executes (executes arrives immediately) immediately) • Since I/O operations always release the GIL, CPU-bound threads will always try to restart • On I/O completion (almost immediately), the GIL is gone so the timeout has to repeat Copyright (C) 2010, David Beazley, http://www.dabeaz.com 53
  • 54. An Experiment • Send 10MB of data to an echo server thread that's competing with a CPU-bound thread Python 2.6.4 (2 CPU) : 0.57s (10 sample average) Python 3.2 (2 CPU) : 12.4s (20x slower) • What if echo competes with 2 CPU threads? Python 2.6.4 (2 CPU) : 0.25s (Better performance?) Python 3.2 (2 CPU) : 46.9s (4x slower than before) Python 3.2 (1 CPU) : 0.14s (330x faster than 2 cores?) • Arg! Enough already! Copyright (C) 2010, David Beazley, http://www.dabeaz.com 54
  • 55. Part 6 Score : Multicore 2, GIL 0 Copyright (C) 2010, David Beazley, http://www.dabeaz.com 55
  • 56. Fixing the GIL • Can the GIL's erratic behavior be fixed? • My opinion :Yes, maybe. • The new GIL is already 90% there • It just needs a few extra bits Copyright (C) 2010, David Beazley, http://www.dabeaz.com 56
  • 57. The Missing Bits • Priorities: There must be some way to separate CPU-bound (low priority) and I/O bound (high priority) threads • Preemption: High priority threads must be able to immediately preempt low-priority threads Copyright (C) 2010, David Beazley, http://www.dabeaz.com 57
  • 58. A Possible Solution • Operating systems use timeouts to automatically adjust task priorities (multilevel feedback queuing) • If a thread is preempted by a timeout, it is penalized with lowered priority (bad thread) • If a thread suspends early, it is rewarded with raised priority (good thread) • High priority threads always preempt low priority threads • Maybe it could be applied to the new GIL? Copyright (C) 2010, David Beazley, http://www.dabeaz.com 58
  • 59. Remove the GIL? • This entire talk has been about the problem of implementing one tiny little itty bitty lock • Fixing Python to remove the GIL entirely is an exponentially more difficult project • If there is one thing to take away, there are practical reasons why the GIL remains Copyright (C) 2010, David Beazley, http://www.dabeaz.com 59
  • 60. Final Thoughts • Don't use this talk to justify not using threads • Threads are a very useful programming tool for many kinds of concurrency problems • Threads can also offer excellent performance even with the GIL (you need to study it) • However, you should know about the tricky corner cases Copyright (C) 2010, David Beazley, http://www.dabeaz.com 60
  • 61. Final Thoughts • Improving the GIL is something that all Python programmers should care about • Multicore is not going away • You might not use threads yourself, but they are used for a variety of low-level purposes in frameworks and libraries you might be using • More predictable thread behavior is good Copyright (C) 2010, David Beazley, http://www.dabeaz.com 61
  • 62. Thread Terminated • That's it! • Thanks for listening! • Questions Copyright (C) 2010, David Beazley, http://www.dabeaz.com 62