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

Improving performance by adding multithreading support #221

Merged
merged 7 commits into from
Sep 21, 2018

Conversation

Zichuan-Wang
Copy link
Contributor

@Zichuan-Wang Zichuan-Wang commented Aug 23, 2018

Hi there,

As some of you may have experienced, currently the UnityGLTF library blocks the main thread when importing models containing complex geometry and/or textures. Although the coroutine approach is used in the project, sometimes multithreading may be a better solution as it provides a non-blocking behavior as well as better performance (in some situations).

Implementation
I noticed a parameter isMultithreaded in GLTFSceneImporter.LoadScene that is never actually used, changed it to a public field and used it as the switch. I put some presumably time-consuming work on other threads (rather than the main thread), which includes LoadStream, ParseJson, stream.Read, buildMeshAttributesThread, and GLTFHelpers.BuildMeshAttributes.

I have to change the ILoader interface to add support for non-coroutine based LoadStreamSync method, as coroutine methods cannot be easily executed on threads and doesn't really make sense for created threads anyway. I also have to change the signature of ParseJson in GLTFParser.cs to make it thread-friendly.

Performance
HUGE frame rate increase for certain models containing complex geometry and/or textures. I observed up to 500% fps increase for this model on a Windows desktop computer. In general, it should increase your fps and/or decrease the main thread freezing time. It should not make any tangible negative impact to the loading time, if no faster loading is observed.

Comparison Chart
image
Model 1: Complex link
Model 2: Complex link
Model 3: Simple link
Model 4: Simple link
Test performed 3 times for each model and each importer (original vs proposed).
Test machine: Windows 10 64 bit, i7 7700K, GTX 1070, SSD.

Limitations
As mentioned in #9, Texture2D.LoadImage is slow and there's no obvious way around it. Same with Texture2D.Apply.

Unity Job System?
The recently introduced Unity Job System seems good, but currently it is still limited in a number of ways. Also, I don't believe it is very backward compatible.

Reference: #216

var stack = new Stack<IEnumerator>();
stack.Push(loader.LoadScene(isMultithreaded: true));
// HACK: Force the coroutine to run synchronously in the editor
var stack = new Stack<IEnumerator>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting seems to be off here. Make sure you're using tabs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm using tabs here, but the rest of this file seems to be using spaces. Should I change the tabs to spaces?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, I think the majority of the project is using tabs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this case whichever keeps the formatting changes to a minimum is best to see the diff.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue fixed!

Copy link

@blgrossMS blgrossMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great change. Thanks for the contribution!

@@ -19,7 +19,7 @@ internal struct GLBHeader
public uint FileLength { get; set; }
}

public static GLTFRoot ParseJson(Stream stream, long startPosition = 0)
public static void ParseJson(Stream stream, ref GLTFRoot gltfRoot, long startPosition = 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be out instead of ref

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was starting to fix it but then noticed you had done it. Thanks!

@@ -57,7 +59,8 @@ public void LoadGLBFromStream()
{
Assert.IsTrue(File.Exists(GLB_PATH));
FileStream gltfStream = File.OpenRead(GLB_PATH);
GLTFRoot gltfRoot = GLTFParser.ParseJson(gltfStream);
GLTFRoot gltfRoot =null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit spacing

@@ -17,11 +17,14 @@ public class WebRequestLoader : ILoader
{
public Stream LoadedStream { get; private set; }

public bool HasSyncLoadMethod { get; private set; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be HasSyncLoadMethod => false;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed you have started CI. Are you OK with leaving it as it is?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's not supported in this version of .NET

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it!

@@ -15,9 +15,12 @@ public class FileLoader : ILoader
private string _rootDirectoryPath;
public Stream LoadedStream { get; private set; }

public bool HasSyncLoadMethod { get; private set; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HasSyncLoadMethod => true

@Zichuan-Wang
Copy link
Contributor Author

@blgrossMS It seems like the CI is failing due to some configuration problems... Could you maybe take a look at it?

@blgrossMS
Copy link

Yup I just have to merge master, I fixed it there

@Zichuan-Wang
Copy link
Contributor Author

Cool, let me know if you need anything from me.

@blgrossMS blgrossMS merged commit 21f73d6 into KhronosGroup:master Sep 21, 2018
github-actions bot pushed a commit to Rhinox-Training/UnityGLTF that referenced this pull request Nov 9, 2022
)

* Added multithreading support.

* Added multithreading support.

* Fixed spacing.

* fixes from PR

* fixed compile error
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.

3 participants