mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 14:48:32 +09:00
[Perf] (MG_State): adopt in-flight compile jobs across shader objects (P1 stage 6)
~21% of a shaderpack's glCompileShader calls hand different shader objects byte-identical source; the P0b cache only helps after one finishes, so under async two workers would run the whole pipeline twice. Now the GL thread consults a per-context (stage, hash, length, envFingerprint) -> weak-node map at enqueue and ADOPTS the in-flight (or completed) node instead of posting a duplicate - a hit is honored only after a full byte comparison (the hash never decides), a cancel-requested or settled-cancelled node is never adopted, and no worker ever waits. Sharing a node makes the unconditional cancel wrong, so release is now adopter-counted: a plain GL-thread Int (every mutation site is a GL entry point; the single-threadedness argument and the terminal-early-out that keeps the count exact are in the header), and the cancel fires only at count zero AND with no pending link pinning the node (the stage-4 MarkLinkReferenced precedence). Adoption also re-points the object's source at the node's snapshot so the layer-1 memo's pointer compare stays armed - without that, an adopter's next glCompileShader would re-enqueue the very duplicate this stage removes. Both guards are negative-control-proven: each removed guard fails exactly its own tests. Count discipline was proven with a temporary hard-abort on underflow/leak across the full suite and retrace corpus - zero hits. 18 new tests (13 GL-surface incl. shared-node re-source/delete/orphan-sweep isolation, shared failure logs, 48-over-6 stress with a deterministic adoption count, flag-off and KHR-suspended zero-adoption guards; 5 direct map cases incl. fingerprint mismatch and cancelled/expired pruning). Gates: 538/538 unit both flag states, async suites x5 no flakes, NVIDIA DirectGLES retrace identical sets both states. Timing: 2-worker (Android-shaped) 1-3% faster consistently on complementary and BSL; 4-worker unchanged - the win this stage exists for lands where CPU is scarce.
This commit is contained in:
@@ -60,6 +60,22 @@ target_link_libraries(
|
||||
${LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(
|
||||
ShaderCompileAdoptionTest
|
||||
ShaderCompileAdoptionTest.cpp
|
||||
)
|
||||
|
||||
target_include_directories(ShaderCompileAdoptionTest PRIVATE
|
||||
${MGL_ROOT}/include
|
||||
${MGL_ROOT}/MobileGL
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
ShaderCompileAdoptionTest PRIVATE
|
||||
GTest::gtest_main
|
||||
${LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(
|
||||
ParallelShaderCompileTest
|
||||
ParallelShaderCompileTest.cpp
|
||||
@@ -113,6 +129,9 @@ gtest_discover_tests(ProgramTest DISCOVERY_TIMEOUT 30 PROPERTIES LABELS unit)
|
||||
# compile pool so there is something in flight to race against.
|
||||
gtest_discover_tests(AsyncCompileTest DISCOVERY_TIMEOUT 60 PROPERTIES LABELS unit TIMEOUT 300)
|
||||
gtest_discover_tests(AsyncLinkTest DISCOVERY_TIMEOUT 60 PROPERTIES LABELS unit TIMEOUT 300)
|
||||
# Same reason: the stage-6 cases keep a backlog in flight so a release really can race a
|
||||
# worker, and the 48-object stress links every one of them.
|
||||
gtest_discover_tests(ShaderCompileAdoptionTest DISCOVERY_TIMEOUT 60 PROPERTIES LABELS unit TIMEOUT 300)
|
||||
# Same reason: the GL_COMPLETION_STATUS_KHR cases saturate a one-worker pool on purpose.
|
||||
gtest_discover_tests(ParallelShaderCompileTest DISCOVERY_TIMEOUT 60 PROPERTIES LABELS unit TIMEOUT 300)
|
||||
gtest_discover_tests(AsyncTeardownTest DISCOVERY_TIMEOUT 60 PROPERTIES LABELS unit TIMEOUT 300)
|
||||
|
||||
Reference in New Issue
Block a user