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
  • 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

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)
    • 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
  • 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

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

Published

01 June 2016

Category

work

Tags