FBX IO: Speed up export by multithreading array compression #105018

Merged
Thomas Barlow merged 6 commits from Mysteryem/blender-addons:fbx_multithread_array_compression_pr into main 2024-01-12 21:39:20 +01:00
Member

zlib.compress() releases the GIL so can be multithreaded.

This patch adds a context manager to FBXElem that temporarily enables
multithreading of the compression of added arrays, by using the recently
added utility to schedule CPU-bound tasks to run on separate threads.

On my Ryzen 7 3800x, exporting non-animated rigged humanoid models
typically results in about a 1.2 to 1.4 times faster export.

Exporting only simple geometry, such as many subdivided default cubes,
can be about 2 to 3 times faster.

The multithreading is also enabled for the json2fbx.py script.

No changes are expected to the contents of exported files.


I'm open to ideas of better ways to temporarily enable the multithreading in FBXElem.

My only other idea was to set FBXElem._add_compressed_array_helper_multi to None in FBXElem's class definition and temporarily set it to the wrapped function that schedules the compression tasks when needed. _add_array_helper would then be updated to always check FBXElem._add_compressed_array_helper_multi is not None when it needs to compress an array. If the check passes it'll use FBXElem._add_compressed_array_helper_multi and if the check fails, it'll do the compression itself.

This PR depends on #105017 (its changes are not included in this PR)

zlib.compress() releases the GIL so can be multithreaded. This patch adds a context manager to FBXElem that temporarily enables multithreading of the compression of added arrays, by using the recently added utility to schedule CPU-bound tasks to run on separate threads. On my Ryzen 7 3800x, exporting non-animated rigged humanoid models typically results in about a 1.2 to 1.4 times faster export. Exporting only simple geometry, such as many subdivided default cubes, can be about 2 to 3 times faster. The multithreading is also enabled for the `json2fbx.py` script. No changes are expected to the contents of exported files. --- I'm open to ideas of better ways to temporarily enable the multithreading in FBXElem. My only other idea was to set `FBXElem._add_compressed_array_helper_multi` to `None` in `FBXElem`'s class definition and temporarily set it to the wrapped function that schedules the compression tasks when needed. `_add_array_helper` would then be updated to always check `FBXElem._add_compressed_array_helper_multi is not None` when it needs to compress an array. If the check passes it'll use `FBXElem._add_compressed_array_helper_multi` and if the check fails, it'll do the compression itself. This PR depends on https://projects.blender.org/blender/blender-addons/pulls/105017 (its changes are not included in this PR)
Thomas Barlow added 2 commits 2023-11-21 07:26:57 +01:00
zlib.compress releases the GIL so can be multithreaded.

This patch adds a context manager to FBXElem that temporarily enables
multithreading of the compression of added arrays, by using the recently
added utility to schedule CPU-bound tasks to run on separate threads.

On my Ryzen 7 7800x, exporting non-animated rigged humanoid models
typically results in about a 1.2 to 1.4 times faster export.

Exporting only simple geometry, such as many subdivided default cubes,
can be about 2 to 3 times faster.

No changes are expected to the contents of exported files.
Thomas Barlow requested review from Bastien Montagne 2023-11-21 07:31:34 +01:00
Thomas Barlow added 2 commits 2023-12-03 01:07:15 +01:00
Bastien Montagne approved these changes 2024-01-10 18:50:22 +01:00
Bastien Montagne left a comment
Owner

LGTM.

Actually, I think I prefer the context manager solution to control when the threaded compression is enabled.

Implementation might be a bit verbose and convoluted, but the usage of it looks much cleaner to me?

Unless I do not get exactly how your other idea would work.

LGTM. Actually, I think I prefer the context manager solution to control when the threaded compression is enabled. Implementation might be a bit verbose and convoluted, but the usage of it looks much cleaner to me? Unless I do not get exactly how your other idea would work.
Author
Member

The other idea was to avoid entirely swapping out existing methods. Rather than swapping out the method, the existing method would be updated to always check for whether a _add_compressed_array_helper_multi attribute on the class is not None and then call that function instead of the existing non-threaded code. The context manager, in that case, would temporarily set the _add_compressed_array_helper_multi attribute on the class to the threaded function.

The other idea was to avoid entirely swapping out existing methods. Rather than swapping out the method, the existing method would be updated to always check for whether a `_add_compressed_array_helper_multi` attribute on the class is not `None` and then call that function instead of the existing non-threaded code. The context manager, in that case, would temporarily set the `_add_compressed_array_helper_multi` attribute on the class to the threaded function.
Thomas Barlow added 2 commits 2024-01-12 21:36:13 +01:00
Thomas Barlow merged commit 2791f29806 into main 2024-01-12 21:39:20 +01:00
Thomas Barlow deleted branch fbx_multithread_array_compression_pr 2024-01-12 21:39:21 +01:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender-addons#105018
No description provided.