From 06d2ea5d308a4aabe8eee25c4e3b7752ecdb39c4 Mon Sep 17 00:00:00 2001 From: "Maarten A. Breddels" Date: Tue, 15 Dec 2020 14:57:07 +0100 Subject: [PATCH] docs: added example3 with gil_load --- .gitignore | 3 ++- README.md | 22 ++++++++++++++++++++++ per4m/example3.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 per4m/example3.py diff --git a/.gitignore b/.gitignore index 4de0fee..12af0d5 100644 --- a/.gitignore +++ b/.gitignore @@ -131,4 +131,5 @@ dmypy.json *.json *.html *.data -*.data.old \ No newline at end of file +*.data.old +*.ipynb diff --git a/README.md b/README.md index eb48a8c..81b622b 100644 --- a/README.md +++ b/README.md @@ -126,3 +126,25 @@ Merge the viztracer and perf/per4m results into a single html file. +## GIL load vs GIL wait + +Even though a thread may have a lock on the GIL, if other don't need it, it's fine. For instance, using [gil_load](https://github.com/chrisjbillington/gil_load): +``` +$ python -m gil_load per4m/example3.py +eld: 1.0 (1.0, 1.0, 1.0) +wait: 0.083 (0.083, 0.083, 0.083) + <139967101757248> + held: 1.0 (1.0, 1.0, 1.0) + wait: 0.0 (0.0, 0.0, 0.0) + <139957774272256> + held: 0.0 (0.0, 0.0, 0.0) + wait: 0.083 (0.083, 0.083, 0.083) + <139957765879552> + held: 0.0 (0.0, 0.0, 0.0) + wait: 0.083 (0.083, 0.083, 0.083) +``` +Show one thread that has a high GIL load, but it does not keep the others from running (except 8% of the time), i.e. wait is low (see [example3.py](https://github.com/maartenbreddels/per4m/blob/master/per4m/example3.py)). We can visualize this using `giltracer` (not that we import numpy and some other modules before tracing to avoid clutter) + + $ per4m giltracer --import="numpy,threading,time,gil_load" -m per4m.example3 + +![image](https://user-images.githubusercontent.com/1765949/102223915-96996400-3ee5-11eb-9e2e-46ac6fd5c5e3.png) diff --git a/per4m/example3.py b/per4m/example3.py new file mode 100644 index 0000000..bbebb60 --- /dev/null +++ b/per4m/example3.py @@ -0,0 +1,42 @@ +# shows high gil load, but no wait +import threading +import time +import numpy as np + +# if we don't run with gil_load, we just skip it +import gil_load +try: + gil_load.init() + use_gil_load = True +except RuntimeError: + use_gil_load = False + + +N = 1024*1024*32 +M = 4 +x = np.arange(N, dtype='f8') + +def run(): + total = 0 + for i in range(M): + total += x.sum() + return total + + +if use_gil_load: + gil_load.start() + +thread1 = threading.Thread(target=run) +thread2 = threading.Thread(target=run) +thread1.start() +thread2.start() +total = 0 +for i in range(1_000_000): + total += i +for thread in [thread1, thread2]: + thread.join() + +if use_gil_load: + gil_load.stop() + stats = gil_load.get() + print(gil_load.format(stats)) \ No newline at end of file