Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel image parsing for low latency use cases #470

Draft
wants to merge 4 commits into
base: release
Choose a base branch
from

Conversation

bekorn
Copy link

@bekorn bekorn commented Feb 2, 2024

Briefly: I developed a gltf parser for my needs but want to switch to a 3rd party solution. Knew tinygltf was an option. Did some testing and it was slow. Wanted to apply the multithreading strategy I used on my parser.

I know that sophisticated projects have their thread managers and can do a better job. The case I optimized for is small apps with the sole purpose of displaying a single model as fast as possible, such as Windows 3D Viewer or gltf-viewers. Or any other case where the latency is important and there are idle cores. I observed x4 or so speedup with gltf files with 40MB+ image files.

The initial implementation with minimal changes I did looked like a hack, so I had to make larger changes. While reading the code, I realized some repetition and made a generic function, ParseArrayProperty, that unified many use cases (see LoadFromString). This function also resizes the vector before any insertion, which prevents any unnecessary allocations.

There is an issue though, I don't get the required argument of Parse*Property functions. It is just a flag that prevents error logging, while the name suggests something that should affect the program flow. Like, if that property is absent, parsing should stop. LoadFromString has such a section that some members are checked and if any are absent, returns false. Also, error logging can be suppressed by passing a nullptr to err as it is already checked.

I implemented the ParseArrayProperty with a different behaviour, which worked for LoadFromString but failed for others. Hence the draft pull request. Do you have any suggestions on what to do? Should I change the argument's name or behaviour?

Also, I measured the time it takes to copy all the pixels from stb_image buffer to a vector, which takes quite a big portion of the parsing process. I think capturing it with a std::unique_ptr can totally eliminate that.

… and passes index to callback, adds ParseStringArrayProperty and uses it for extension parsing
…son array into a vector<T>

This makes ParseNumberArrayProperty, ParseIntegerArrayProperty, and ParseStringArrayProperty just special cases of the base function.
ParseObjectArrayProperty is also a special case which replaces ForEachObjInArray.
ParseArrayProperty also resizes the vector to the json array's size before iteration, preventing any extra allocations. As a side effect, this gives pointer stability during the parsing operation.
@syoyo
Copy link
Owner

syoyo commented Feb 2, 2024

If the parsing speed is dominated by image decoding, I think preferred approach would be using delayed decoding strategy.

#177 (comment)

This will keep code change small. PR of having delayed(threaded) decoding of images by default would be nice.

For refactoring Parse*Property. Please create another PR(or Issue) to discuss it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants