Skip to main content

๐ŸŒ€ Faster ModernGL Buffer inter process data transfers

Reason this release was yanked:

Broken Windows CI builds

Project description

[!IMPORTANT] Also check out ShaderFlow, where TurboPipe shines! ๐Ÿ˜‰

TurboPipe


Faster ModernGL inter-process data transfers

๐Ÿ”ฅ Description

TurboPipe speeds up sending raw bytes from moderngl.Buffer objects primarily to FFmpeg subprocess

The optimizations involved are:

  • Zero-copy: Avoid unnecessary memory copies or allocation (intermediate buffer.read())
  • C++: The core of TurboPipe is written in C++ for speed, efficiency and low-level control
  • Chunks: Write in chunks of 4096 bytes (RAM page size), so the hardware is happy
  • Threaded:
    • Doesn't block Python code execution, allows to render next frame
    • Decouples the main thread from the I/O thread for performance

โœ… Don't worry, there's proper safety in place. TurboPipe will block Python if a memory address is already queued for writing, and guarantees order of writes per file-descriptor. Just call .sync() when done ๐Ÿ˜‰


๐Ÿ“ฆ Installation

It couldn't be easier! Just install in your package manager:

pip install turbopipe
poetry add turbopipe
pdm add turbopipe
rye add turbopipe

๐Ÿš€ Usage

See also the Examples folder for more controlled usage, and ShaderFlow usage of it!

import subprocess
import moderngl
import turbopipe

# Create ModernGL objects
ctx = moderngl.create_standalone_context()
buffer = ctx.buffer(reserve=1920*1080*3)

# Make sure resolution, pixel format matches!
ffmpeg = subprocess.Popen(
    'ffmpeg -f rawvideo -pix_fmt rgb24 -s 1920x1080 -i - -f null -'.split(),
    stdin=subprocess.PIPE
)

# Rendering loop of yours
for _ in range(100):
    turbopipe.pipe(buffer, ffmpeg.stdin.fileno())

# Finalize writing
turbo.sync()
ffmpeg.stdin.close()
ffmpeg.wait()

โญ๏ธ Benchmarks

[!NOTE] The tests conditions are as follows:

  • The tests are the average of 3 runs to ensure consistency, with 3 GB of the same data being piped
  • The data is a random noise per-buffer between 128-135. So, multi-buffers runs are a noise video
  • All resolutions are wide-screen (16:9) and have 3 components (RGB) with 3 bytes per pixel (SDR)
  • Multi-buffer cycles through a list of buffer (eg. 1, 2, 3, 1, 2, 3... for 3-buffers)
  • All FFmpeg outputs are scrapped with -f null - to avoid any disk I/O bottlenecks
  • The gain column is the percentage increase over the standard method
  • When x264 is Null, no encoding took place (passthrough)
  • The test cases emoji signifies:
    • ๐Ÿข: Standard ffmpeg.stdin.write(buffer.read()) on just the main thread, pure Python
    • ๐Ÿš€: Threaded ffmpeg.stdin.write(buffer.read()) with a queue (similar to turbopipe)
    • ๐ŸŒ€: The magic of turbopipe.pipe(buffer, ffmpeg.stdin.fileno())

Also see benchmark.py for the implementation

โœ… Check out benchmarks in a couple of systems below:

Desktop โ€ข (AMD Ryzen 9 5900x) โ€ข (NVIDIA RTX 3060 12 GB) โ€ข (DDR4 2x32 GB 3200 MT/s) โ€ข (Arch Linux)
720p x264 Buffers Framerate Bandwidth Gain
๐Ÿข Null 1 882 fps 2.44 GB/s
๐Ÿš€ Null 1 793 fps 2.19 GB/s -10.04%
๐ŸŒ€ Null 1 1911 fps 5.28 GB/s 116.70%
๐Ÿข Null 4 818 fps 2.26 GB/s
๐Ÿš€ Null 4 684 fps 1.89 GB/s -16.35%
๐ŸŒ€ Null 4 1494 fps 4.13 GB/s 82.73%
๐Ÿข ultrafast 4 664 fps 1.84 GB/s
๐Ÿš€ ultrafast 4 635 fps 1.76 GB/s -4.33%
๐ŸŒ€ ultrafast 4 869 fps 2.40 GB/s 31.00%
๐Ÿข slow 4 204 fps 0.57 GB/s
๐Ÿš€ slow 4 205 fps 0.57 GB/s 0.58%
๐ŸŒ€ slow 4 208 fps 0.58 GB/s 2.22%
1080p x264 Buffers Framerate Bandwidth Gain
๐Ÿข Null 1 385 fps 2.40 GB/s
๐Ÿš€ Null 1 369 fps 2.30 GB/s -3.91%
๐ŸŒ€ Null 1 641 fps 3.99 GB/s 66.54%
๐Ÿข Null 4 387 fps 2.41 GB/s
๐Ÿš€ Null 4 359 fps 2.23 GB/s -7.21%
๐ŸŒ€ Null 4 632 fps 3.93 GB/s 63.40%
๐Ÿข ultrafast 4 272 fps 1.70 GB/s
๐Ÿš€ ultrafast 4 266 fps 1.66 GB/s -2.14%
๐ŸŒ€ ultrafast 4 405 fps 2.53 GB/s 49.24%
๐Ÿข slow 4 117 fps 0.73 GB/s
๐Ÿš€ slow 4 122 fps 0.76 GB/s 4.43%
๐ŸŒ€ slow 4 124 fps 0.77 GB/s 6.48%
1440p x264 Buffers Framerate Bandwidth Gain
๐Ÿข Null 1 204 fps 2.26 GB/s
๐Ÿš€ Null 1 241 fps 2.67 GB/s 18.49%
๐ŸŒ€ Null 1 297 fps 3.29 GB/s 45.67%
๐Ÿข Null 4 230 fps 2.54 GB/s
๐Ÿš€ Null 4 235 fps 2.61 GB/s 2.52%
๐ŸŒ€ Null 4 411 fps 4.55 GB/s 78.97%
๐Ÿข ultrafast 4 146 fps 1.62 GB/s
๐Ÿš€ ultrafast 4 153 fps 1.70 GB/s 5.21%
๐ŸŒ€ ultrafast 4 216 fps 2.39 GB/s 47.96%
๐Ÿข slow 4 73 fps 0.82 GB/s
๐Ÿš€ slow 4 78 fps 0.86 GB/s 7.06%
๐ŸŒ€ slow 4 79 fps 0.88 GB/s 9.27%
2160p x264 Buffers Framerate Bandwidth Gain
๐Ÿข Null 1 81 fps 2.03 GB/s
๐Ÿš€ Null 1 107 fps 2.67 GB/s 32.26%
๐ŸŒ€ Null 1 213 fps 5.31 GB/s 163.47%
๐Ÿข Null 4 87 fps 2.18 GB/s
๐Ÿš€ Null 4 109 fps 2.72 GB/s 25.43%
๐ŸŒ€ Null 4 212 fps 5.28 GB/s 143.72%
๐Ÿข ultrafast 4 59 fps 1.48 GB/s
๐Ÿš€ ultrafast 4 67 fps 1.68 GB/s 14.46%
๐ŸŒ€ ultrafast 4 95 fps 2.39 GB/s 62.66%
๐Ÿข slow 4 37 fps 0.94 GB/s
๐Ÿš€ slow 4 43 fps 1.07 GB/s 16.22%
๐ŸŒ€ slow 4 44 fps 1.11 GB/s 20.65%
Desktop โ€ข (AMD Ryzen 9 5900x) โ€ข (NVIDIA RTX 3060 12 GB) โ€ข (DDR4 2x32 GB 3200 MT/s) โ€ข (Windows 11)

๐ŸŒ€ Conclusion

TurboPipe significantly increases the feeding speed of FFmpeg with data, especially at higher resolutions. However, if there's few CPU compute available, or the video is too hard to encode (slow preset), the gains are insignificant over the other methods (bottleneck). Multi-buffering didn't prove to have an advantage, debugging shows that TurboPipe C++ is often starved of data to write (as the file stream is buffered on the OS most likely), and the context switching, or cache misses, might be the cause of the slowdown.

Interestingly, due either Linux's scheduler on AMD Ryzen CPUs, or their operating philosophy, it was experimentally seen that Ryzen's frenetic thread switching degrades a bit the single thread performance, which can be "fixed" with prepending the command with taskset --cpu 0,2 (not recommended at all), comparatively speaking to Windows performance on the same system (Linux ๐Ÿš€ = Windows ๐Ÿข). This can also be due the topology of tested CPUs having more than one Core Complex Die (CCD). Intel CPUs seem to stick to the same thread for longer, which makes the Python threaded method an unecessary overhead.

Personal experience

On realistically loads, like ShaderFlow's default lightweight shader export, TurboPipe increases rendering speed from 1080p260 to 1080p330 on my system, with mid 80% CPU usage than low 60%s. For DepthFlow's default depth video export, no gains are seen, as the CPU is almost saturated encoding at 1080p130.


๐Ÿ“š Future work

  • Add support for NumPy arrays, memoryviews, and byte-like objects
  • Improve the thread synchronization and/or use a ThreadPool
  • Maybe use mmap instead of chunks writing
  • Test on MacOS ๐Ÿ™ˆ

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

turbopipe-1.0.2.tar.gz (99.8 kB view details)

Uploaded Source

Built Distributions

turbopipe-1.0.2-cp312-cp312-win_amd64.whl (44.5 kB view details)

Uploaded CPython 3.12 Windows x86-64

turbopipe-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

turbopipe-1.0.2-cp312-cp312-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

turbopipe-1.0.2-cp311-cp311-win_amd64.whl (44.6 kB view details)

Uploaded CPython 3.11 Windows x86-64

turbopipe-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.6 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

turbopipe-1.0.2-cp311-cp311-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

turbopipe-1.0.2-cp310-cp310-win_amd64.whl (44.6 kB view details)

Uploaded CPython 3.10 Windows x86-64

turbopipe-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.6 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

turbopipe-1.0.2-cp310-cp310-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

turbopipe-1.0.2-cp39-cp39-win_amd64.whl (44.6 kB view details)

Uploaded CPython 3.9 Windows x86-64

turbopipe-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.6 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

turbopipe-1.0.2-cp39-cp39-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

turbopipe-1.0.2-cp38-cp38-win_amd64.whl (44.6 kB view details)

Uploaded CPython 3.8 Windows x86-64

turbopipe-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (29.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

turbopipe-1.0.2-cp38-cp38-macosx_11_0_arm64.whl (30.9 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

turbopipe-1.0.2-cp37-cp37m-win_amd64.whl (44.6 kB view details)

Uploaded CPython 3.7m Windows x86-64

turbopipe-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (29.8 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

File details

Details for the file turbopipe-1.0.2.tar.gz.

File metadata

  • Download URL: turbopipe-1.0.2.tar.gz
  • Upload date:
  • Size: 99.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for turbopipe-1.0.2.tar.gz
Algorithm Hash digest
SHA256 36c76f6ba34af136b31bcb851cae40030e73e03f5355334a607ce2e74639dc20
MD5 1a2624652c32d821429e2dcfb0c0669a
BLAKE2b-256 014e10d520679ad405390ab11cacbc68d75473264ccff91725d6a04f06c8d161

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e1c502b5e89b21419449bde1a6ececd3128a277878809d63bcd6b29cd2a8b2ca
MD5 071a2a3eabf3683b7632c00105b7e40a
BLAKE2b-256 c603d791af4300d0241ecba8d6d9fdd5260869efed0652e7a54502a0e5c5c869

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5518646ec6363b6eb9ad1b257646bf8ec7bb299d009535aa16590c1db01b7cea
MD5 f9a9d7ccfcfa4bfdc4e377174c0a5165
BLAKE2b-256 4e4c4125b01413690a7df2753eece590ed9121f3990786cb86eed8ac260c2d5f

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ca38ef3170c3b5b78268bee1d2650d20749ac6c21907d3bba0a1afd156acfbe7
MD5 1206552a6342581886f07b18e680f560
BLAKE2b-256 bc79363c4e2097f76137eb61be31ab45714c1a6bf5e19182b22a2dee15284755

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2720882cfb84b7156bfbe84110b2526eceb62bf91db10dbad9f20419fce469d8
MD5 453cd2dd782c2852926f1b4482050073
BLAKE2b-256 96acd2981e8b7f0777059016e9ae6cb4e5cff13a201d81ef06ef3f4fa0f2001f

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c6820537785d0ebaa4bbf73c0ba168dc215fbc63019251119ab29eaa82bcddc9
MD5 1fac2f43b933b3d548d7128f1a38b038
BLAKE2b-256 566cabcce400a74a4c1b7aae9f71cf4242ef4df464f4ff6c4ece25854e70c0a9

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 27b88ba840d778988f2f8685a7b7262a51770594ed9332341048a640d8f990ce
MD5 c66f3fbcc991101747e024158a8eeb13
BLAKE2b-256 f12a3384a5b5f4edc8e605a84370d7678ccb5c61ba42a85711eaa0f08894faaf

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 d7cb3e7720e2a3118399ca6f7e245a74fbbee763d6a02c75b1dca5b48885a434
MD5 16a6df41334d430e933611c4a3d9286e
BLAKE2b-256 a381abf4f68ac14a0c7c01f7de0d21ffcfb8e01ad8849ffbd1212cc9d62b1a5a

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9cdbd1a9330488654f393232252d4f0fe00929c7d223e5144ae9933a619f7cfc
MD5 ef31d0833a49472d3acad579ae92ed4f
BLAKE2b-256 1762e2ddc3055bd2d3b000e9e62a400d9cdce0ade174c354e55f1d841440b4c8

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 807338754047f1e1d88edae0a076a7fc46b6e7824c9b8abdabca77af4f0512b0
MD5 90321064976d9ac526e394e9f2e102ea
BLAKE2b-256 32792ee7ea229cf48d5078d56b830238e0c3e0cbff75f55d3caec14e57cf81aa

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: turbopipe-1.0.2-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for turbopipe-1.0.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 9003dda6bd9aaba8eaf54039d0babc42a5561e7d0e39ad4340ba4865412564e2
MD5 bcd708b8da698265eb46955685bad635
BLAKE2b-256 a67dbcf3899dc78f7b2ad168b25e8231bab7bf963329a27e2174beccc6373cd5

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8d4a309aba65f8ffbefda510e1d593ec9d7ae136344a7f7957d25aa2c61ec375
MD5 aff3fd509eb0713c80adb7cf64f7bbf5
BLAKE2b-256 aa9e55a1ab0d374b6c33492f3e9d1af61cae7d92f990de0faf464ef101471020

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f0d700fa99fe73d7cc6cbedeff75ba4dc7e011bb07f19ad77b61bc68e2251c71
MD5 4df6264a44e26099594057126f384451
BLAKE2b-256 45717b20d9da2481a9a489d4f7dbe8b55a0192d1fbc191f2c3f5b56abd0f7f4e

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: turbopipe-1.0.2-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for turbopipe-1.0.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 089b0725ac43addda1e676d083e26b9a80e9e6f115a59dfc29fdf463129afefc
MD5 197a03c9de83dfa6948ba04d6a81c007
BLAKE2b-256 6b0af29703682b8c1a03aefe406a98bd776822c7f31701114a464b93838e1190

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f90f7752dac2724553505a891099997b9ea2474b258130249ea9064fa94ccc49
MD5 3cc2ed01a9387bf0604c4071dbc1cd79
BLAKE2b-256 be0404f93b77e6e2a01b67f83675777d73e2607c8e9fa9cfc5ab5c64d40e60b8

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3b3144b5781d56f979f5b81559927c91c29b762b1eab801adbec77356eaf739a
MD5 f6df3f403078fe6ad717d27436ba35dc
BLAKE2b-256 f318030615cb4b98afeea091f50873b4fef0cc9e678fb63d69e5591cd06c3228

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: turbopipe-1.0.2-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for turbopipe-1.0.2-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 85101a1f76f46f6afcc19f884c7b98c808ebd2ed2fee64b11cacce6c84597a98
MD5 074376eb6abbf2fd6edeef1bf7e45d65
BLAKE2b-256 8ede105eeb41c960c46c0f183e120caafe766470d7017e77f3436a6692572924

See more details on using hashes here.

File details

Details for the file turbopipe-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for turbopipe-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5c07dff93f4ab6de34d33a254c935428457c21380ca1e002d94f0eeb27658588
MD5 e6b31ae351aa73241f2940a146eae455
BLAKE2b-256 579648172ed2d162a5f0ae82862c3aa599138df6bcdb54429dfa735b5dcb16b9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page