PyCon Day 4: Afternoon sessions
See Python, See Python Go, Go Python Go
Do you Go?
- Simple syntax that is easy to learn
- Compiles super fast
- Statically typed
- Statically linked binaries
- Cross-compiles to ~every platform
- Easy concurrency
- Great standard library
- Gophers
Go in Python
import os
os.system("go run main.go")
Just kidding
Fun facts
- Python speaks with C
- Go speaks with C
- Therefore, Python speaks with Go? Right?
- This applies to any two language pairs that speak with C
Challenges
- Runtine barriers
- GC
- GIL
- JIT*
- Threads
- All of these mutate state during runtime
- Syntax and feature barriers
- Go: Interface, Goroutines, etc
- Python: Classes, generators, etc
Imagine
package main
import (
"fmt"
"net/http:
)
func index() {
}
func main() {
}
from gohttp import route, run
...
- https://github.com/shazow/gothttplib
- This is an actual functioning thing
The Plan
- Go Export Go functions to a C shared library
- other stuff
Calling C from Go
import "C"
Calling Go from C
package main
import "C"
func TheAnswer() c.int {
return C.int(42)
}
$ go build -buildmode=c-shared -o libanswer.so
#include libtheanswer
See CPython C
- CPython Extension Interface: no dependencies, but lots of boilerplate
- CFFI: a little more magic but does more work for us and more portable
Calling C from Python
from cffi import FFI
ffi = FFI()
ffi.cdef("int the_answer();")
Overcoming challenges
- Don’t share memory!
- Translation layer
- Things like interfaces
- Summary
- Original interface in Go
- Exported interface from Go
- C header
- Access C from python (CFFI)
- Python writer
- Seriously, don’t share memory!
- An interface is a pointer
- To use it we need to pass a pointer through Go -> C -> Python -> C -> Go
- To get around this?
- Pointer Proxy, 20 LOCs
- “If you’ve every implemented an OS it’s much more complicated than this
- In the callback, reference pointers to bind them
- In the pointer proxy, dereference to get them
Recap
- If our language can speak with C, they can speak with each other
- Be careful going in and out of runtimes
- Be super careful with sharing memory
- We’ll need a translation layer to get memory from one to the other
- Other considerations (it won’t be all rosy)
- Memory leaks
- Race conditions
- Context switching overhead
- Probably security issues because C is hard
- Architecture campanelle/spaghetii
- You’re going back/forth across 3-4 barriers each way
Benchmarks (Pallate cleanser)
They exist
Resources
- https://github.com/shazow/gohttplib
- http://hrku.co/gopythongo
- http://twitter.com/shazow
- http://shazow.net
Python and Emacs open space
I’ve never actually gone to an Open Space before, but there weren’t any talks that I wanted to go to during this slot so I wandered into this room. I was only there for a few minute, but I learned about a ton of useful things that exist.
- elpy
- anaconda
- spacemacs
- whichkey
- projectile - library for searching through a git repo
- vevim pip, vevim python
- ein (emacs IPYthon Notebook) org-mode is good for that too
- C-h m all of the keybindings that are active
- hydra… YA way to solve the pinky problem
Python’s Infamous GIL: Performing a GIL-ectomy
Larry Hastings
Preface
- Exceedingly technical
- Multithreading
- CPython internals
- cf. “Python’s Infamous GIL”
- History
- Added in 1992 by Guido
- Interested in this new OS thing called “threading”
- Great design
- Wonderful features
- I’m not a GIL hater
- Ramifications
- Simple
- Easy to get right
- No deadlocks
- Low overhead
- Single-threaded code is fast!
- I/O bound: OK! (This was the original use-case of threads)
- CPU bound: not good… single-threaded
- Simple
- The world has changed
- Everything is now multi-core
- Python is still doing single-core
- Your computer’s resources
- Python can take advantage of all of them, except for 8 cores
- Attempt to remove the GIL
- Python 1.4, 1999
- No C API changes
- interpreter globals ->
stuct (PyThreadSafe)
- mutex lock around incr/decr
- 4x - 7x slower
- Removing the GIL makes your code slow!
- “An Inside Look at the GIL Removal Patch of Lore” ~dabeaz
Technical Considerations
- Reference Counting
- Multiple threads can have a race between them when incr/decr the ref counts
- Globals and Statics
- Would have to have the per-thread
- Shared singletons (like small integers)
- C Extension Parallelism and Reentrancy
- A C ext has never lived in a world where it can run in more than one thread at one time
- Atomicity
Political (Community) Considerations
- Don’t hurt single-threaded performance ~Guido
- Don’t break C Extensions
- We did that in Python 3.0 and it took a looooong time to recover from that
- Don’t make it too complicated
- That’s subjective, but…
Tracing Garbage Collection
- This is what everybody else does
- C, Java, Go, Rust, etc.
- This is about as fast
- Breaks the C API
- Introduces complexity
Software Transactional Memory
- Waaaaaaaaaaaaaaaay cooler
- But also very early in development
- Veeeeery hard to get right
- Amazing performance
- Would break every C section out there
- Much more complexity
My proposal
- Reference counting stays
- Atomic incr/decr
- You get free with every Intel processor
- Guarantees that no thread can compete with each other
- 30% slower off the top
- per-thread
- PyThreadState
- Shared singletons
- stay shared
- C Ext Parallelism and Reentrancy
- YES
- Atomicity
- This is where we replace one giant lock with millions of little locks
Py_LOCK(o)
Py_UNLOCK(o)
PyTypeObject
- What needs to be locked?
- all mutable objects (e.g. str)
- Userspace locks
- Only uses userspace resources (e.g. RAM) until there is contention
- linux futex
- windows critical_section
- OSX pthread_mutex
- How does it address political constraints
- two builds
./configure -with-gil && ./configure -without-gil
- two entry points on shared libraries
initmodule()
vs.nogil_initmodule()
- This allows extension module authors to opt-in rather than just causing breakage
- A single
.so
? - Since this is a new API, should we enforce best practices?
- e.g.
PyType_Ready
- PEP 489 (multiphase C extension initialization)
- e.g.
- These things make it a bit more complicated
- “It isn’t easy to remove the GIL” ~Guido
- How?
- Atomic incr and decr
- pick lock
- lock dictobject
- lock listobject (you cannot run the interpreter w/o working lists and dicts)
- lock 10 freelists
- disable (cyclic) gc, track and untrack
- murder the GIL
- use TLS thread state
- fix tests
- Language Summit Benchmarks
- 3.5x slower wall time
- 25x slower CPU time (4% of the time, it’s doing your work, 96% of the time it’s doing something else)
- At 1 thread, it’s not much slower (in wall time)
- Gilectomy’s official benchmark
- fibonnocci
- Why is it so slow?
- Lock contention?
- Some… but not the major thing
- Synchronization and cache miss
- atomic incr/decr blows away the cache half a billion times
- Nothing is private
- I’m doing the safe thing, C Python doesn’t have to do that
- Lock contention?
- Where do we go from here?
- Modify the code to guarantee that we’re only doing incr/decr in one thread
- Then we can do it the fast, non-safe way
- Reference counting
- buffered reference counting
- immortal objects
- coalesced reference counting
- Thread-private locking
- We’re adding threads to millions of objects
- Garbage collection
- All sorts of research into concurrent GC
- Stop-the-world
- Buffered track/untrack
- Auto-lock around C extensions?
- Then they can run under a private GIL?
Conclusions
- “A journey of a thousand miles starts with a single step”
- https://github.com/larryhastings/gilectomy
Closing Remarks
Jessica McKellar, PyCon’s Diversity Chair
KSplice, DropBox
- PyCon talks by women, 40%
- It was never about Python
- It was about systems
- Programming changes the way you think about and debug and interact with the world
- You learn a set of rules, you learn how to change the rules and break the rules
- Programmers master a system they know they can change
- The tenants of free software give us explicit permission to do this
- You can always:
- run
- study/change
- redistribute
- distribute
- Sometimes we take for granted what a collective power this is
- Programming has rules (that you can change)
- Everything that is important is a system (that you have the power to change)
- There are software systems, there are hardware systems, there are people systems
- This is why I love to teach people programming. Because it help people realize that they can master a system that they know they can change.
- _____ has rules (but you can change those rules).
- No one will ever invite us to change the rules
- No one will ever tell us how to interact with the system
- Ability: the power to change the system with confidence
- Don’t forget that you have that power
More Closing Remarks
- Total Count: 3209 received badges
- Winners of the 5k
- Carrie Hughes-Cromwick
- Samuel Woo
- PyLadies Auction $16,000 for conference scholarships
- PyLadies Lunches, gifted with scholarships
- PyCon 2017
- Portland 17-25 May
- PyCon 2018/2019
- Cleveland, Ohio May
- Where next?
- Had to answer lots of e-mails from people who wanted to come
- Not sure that PyCon can take on 4000-5000 person conference
- PSF may not want to take on that risk
- Alternatives
- Meetups
- Regional
- SciPy
- PyData
- GeoPython
- DjangoGirls
- The story of the next few years is that we need to become distributed
Closing Keynote
K Lars Lohn
Notes will do this no justice. Just go watch the video. Go… do it now.
blog comments powered by Disqus