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.3.tar.gz (99.8 kB view details)

Uploaded Source

Built Distributions

turbopipe-1.0.3-cp312-cp312-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.12 Windows x86-64

turbopipe-1.0.3-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.3-cp312-cp312-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

turbopipe-1.0.3-cp311-cp311-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.11 Windows x86-64

turbopipe-1.0.3-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.3-cp311-cp311-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

turbopipe-1.0.3-cp310-cp310-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

turbopipe-1.0.3-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.3-cp310-cp310-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

turbopipe-1.0.3-cp39-cp39-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.9 Windows x86-64

turbopipe-1.0.3-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.3-cp39-cp39-macosx_11_0_arm64.whl (30.8 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

turbopipe-1.0.3-cp38-cp38-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

turbopipe-1.0.3-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.3-cp38-cp38-macosx_11_0_arm64.whl (30.9 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

turbopipe-1.0.3-cp37-cp37m-win_amd64.whl (23.8 kB view details)

Uploaded CPython 3.7m Windows x86-64

turbopipe-1.0.3-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.3.tar.gz.

File metadata

  • Download URL: turbopipe-1.0.3.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.3.tar.gz
Algorithm Hash digest
SHA256 a01a09dcc075bb1b76890aac7b2a87978d0ba6ad319c330af46364d3451a296d
MD5 8cf4e67f3a1397d2c1cedb760fe23705
BLAKE2b-256 56750c3483c61069d691d7fef7965846cd7a828e433e80b4b986fc0ef869b778

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 511b07c99faa66cf72cf0fd66d2f4599a5392704f38fac5138a1914a802ee9da
MD5 241542f78552a66989e0b5fdf59350ac
BLAKE2b-256 f907edd5c49bcb471ed0d26f5b059bce0148cdc8f8606cdb9c0c04c85d3509eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 565f0a3d74e3e2e413340a435ef87211c85dbea4ef448eb3297be0abe2f4c0c8
MD5 2215aca73be60b9743345f28cd73648d
BLAKE2b-256 3322a0c5d269e22c9408ce92c1075ab89eca7830ff15ec26664276b5a1a4237d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 55b83b6126dce664c8bf0e93ba1a80f429f590fdb943667d1f192a507fb9af27
MD5 6826e451dae1dbdf4d27506c897f9768
BLAKE2b-256 41daf217a3f616d5a300989bdc8fd98ffc4be3649213804b92e1ea037c2fcfd2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 626bde408008d0d5086eccaf231b925445fdd7f61d4d000cb95b93ce1880c32a
MD5 8f83a1e05b8587d6bb3e5536a8aa2607
BLAKE2b-256 20366757352990c7749e51c67859144fed87171446843d0d4294a386b8017e8b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 62dd32f7dc44f840288e05512b38980c275ea6e5c5fb05efa2b1d8794370c3fe
MD5 cf333b677e2800fe25916f37edfdadef
BLAKE2b-256 f11d7a704a36b156d5c3e1f706c00f976e6e39ae3e11af16b5c82331c63f720d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9343ef9c3c195f0e689a2874518e4ac10a99c2736531c58a74602d34db107ab9
MD5 bf95ffb0ff0eccde6e987061f9dad1ca
BLAKE2b-256 475335297e88d98d9238ae32eabe6b342ec4511ebea1aba8a9b3a9d5d8ba6bd6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 1b0b7d0628393ada9a371a16d188e87c99f952214b80ba8a3b6693cdf901c78f
MD5 8d1d6e644284e8875da8b1f263be0e62
BLAKE2b-256 05057245f9c0a7c643d8a6c199671eeb6eebfcb42c1103f1b7666eb0050036eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c76583510544e3aff5767883b0fa39b020fef6f15f780fba53295c9f1ece6985
MD5 7c5a90e6d0356a9d32204a1988c064e8
BLAKE2b-256 0cf287968e73fd8bfbfa604ff9f3754d7b740c35679d05c15a54d6270eb9cbc0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 62f9da34198d70544023cd1f63fd13c6a02615ea73e77dddfc13d8e73456c830
MD5 72c39f90e27bfa370193f497437a827c
BLAKE2b-256 253291c4ff3395e36b59f9f35e6d61c54b843d9902605c1c994ec550d1b4603d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: turbopipe-1.0.3-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 23.8 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.3-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 663ba8b0a5e8c17764ae8d2b05a8d9102e414fe312dd88a4421ccb62033ede16
MD5 08b12dc4d128048f25c21afcaf2a1a62
BLAKE2b-256 66efc1e04e457b4e2d3fd1f6132c4a2570f1b8e0bb1e4d5bc13d42a2e9e6396f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d928c9d186705190e7c1ae834611e80e220edddab99bea18573acb149e231204
MD5 894eb39a194c5d81fb55a5a74afdb9a1
BLAKE2b-256 f308e90bb8a3ef4ace68da60260124c9554b1c72b1017afaaa65ad463de36b7c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 41b16fad1909532cf471d65792d2976a727f5cd3ac972fd08d63923cc2c1c444
MD5 1c2c0e74d9c3beef543ef5979ae8fbae
BLAKE2b-256 c09c6e0623a03b243dbf1ea93df1737178e53625d06aa7c6cbdd8abdccbd7c20

See more details on using hashes here.

File details

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

File metadata

  • Download URL: turbopipe-1.0.3-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 23.8 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.3-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 5d60881a06e7248f8ceba8932246057b8cfff6c36b528c08370a9f07f628d1b1
MD5 5d2bac32d7bd14b69a92c5d7137f5b91
BLAKE2b-256 def2382736ce016d1ef7185030a26504844e0e6d957cc68a9a521482948fbdc1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 069e8a08a1156a8032fd4999e0ff2d195aba8c356672f45c7f9ba1b4f29e414d
MD5 072203f5ac2d54a43337b7142b336e8b
BLAKE2b-256 a2253cf851d8bff3cbdac6376d5736a00f9815abdfec86ed5e06760d766198fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aca37df0228c3675a8052766cabcbc40cf27eafc564cc3ef2561e10da9cae455
MD5 4f07e78f8372d57a3eeec429544ff279
BLAKE2b-256 b3ee06c48777a15e617c99ea9e9882cc676c9f34f0f058292a52c7e1a70fc861

See more details on using hashes here.

File details

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

File metadata

  • Download URL: turbopipe-1.0.3-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 23.8 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.3-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 eeb40bf8f22e198fdf4656388183bda98a147fbde220d18d49425ba07d383928
MD5 3f694287fbff6557d4614bd2f54abdb8
BLAKE2b-256 f34699750450581705a1d9b27558b7e110b3b30a25a1b410bd0cd978915ab5e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for turbopipe-1.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 72f5932c8e2799250fdd60b9262e82b5376f66cae37fb36accebdda548884a9d
MD5 8bc314af6a9c831cc62195d017b7b020
BLAKE2b-256 63a57a5b58fd971bc998557a7efc99f7085403d62d5558d2678023a53ad8dd36

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