-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
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
SurfaceTool's AppendFrom is extremely slow on separate thread. #51311
Comments
@Delpire Can you reproduce this in a GDScript project to rule out C#/Mono being the issue here? |
@Calinou - Sorry it took me a little bit to recreate it in gdscript as I am not very familiar with gdscript. I am sure the code can be a lot better. I went ahead and downloaded Godot 3.3.2 (the regular build, no mono support). SurfaceToolAppendFromGDScript.zip I also realized my benchmark isn't exactly correct. I was timing both the AppendFrom as well as the rest of the surface tool stuff like generating normals, committing, etc. If I just benchmark the AppendFrom the performance is even worse. ~140ms synchronously |
The AppendFrom function internally calls OpenGL has to run from the main thread only. Not only that, but when you request data back from the GPU, the main thread has to stall while it waits for the data to be returned. That is likely what is happening in your case. You are asking for GPU data 125 times and the main thread stalls while the GPU transfers 125 copies of your mesh to the CPU. (See https://docs.godotengine.org/en/stable/tutorials/optimization/using_servers.html#getting-data-from-the-servers) In your case, you will be much better off by requesting a single copy of the mesh, converting it to an ArrayMesh once and then adding that ArrayMesh's arrays manually. You can even just copy the logic from the godot/scene/resources/surface_tool.cpp Lines 776 to 811 in 8db0bd4
The fact that |
@clayjohn - Thank you so much for the explanation. I wanted to use the ArrayMesh originally, but didn't want to have to apply the transforms myself. I should be able to do this myself, although it would be nice if the SurfaceTool provided a way of doing this since its possible there could be some performance gain doing this in the C++ layer. If anyone feels strongly about it, I could write a proposal in the proposal repo. Regardless, I think this sufficiently resolves my issue, and I think it would be valuable to document APIs that are good candidates for multithreading and APIs that are not. Thank you! |
@Delpire I agree, if there is enough interest a |
Closed by #54982. |
just to supplement @clayjohn comment - since OpenGL has to run from the main thread, See 3 random stack traces from
|
Godot version
3.3.stable.mono.official
System information
Windows 10, RTX 2080, GLES3
Issue description
There may be a good reason for this that I am unaware of, however it seems like the SurfaceTool's AppendFrom method is unusually slow if you execute it from a separate thread.
For my minimal reproduction project, I have a fairly small mesh, 507 verts, and I am looping 125 times to create 125 instances inside of my surface tool. I have written the code such that the only thing that should be running on a separate thread is
Anything else, like generating normals, committing, setting the material, etc., should all be done back on the main thread.
If I execute the code synchronously (on the main thread), it takes ~1100ms.
If I execute the code asynchronously it takes ~11,000ms.
This is 10x slower.
Steps to reproduce
Minimal reproduction project
SurfaceToolAppendFromRepo.zip
The text was updated successfully, but these errors were encountered: