mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Add unit tests for the job system
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "threading.h"
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
extern uint32_t randomSleepRange;
|
||||
extern uint32_t randomSpinRange;
|
||||
};
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
#include "catch/catch.hpp"
|
||||
|
||||
bool isSorted(const rdcarray<int> &arr)
|
||||
{
|
||||
if(arr.size() <= 1)
|
||||
return true;
|
||||
|
||||
for(size_t i = 0; i < arr.size() - 1; i++)
|
||||
{
|
||||
if(arr[i] > arr[i + 1])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// helper function - we don't do this with multiple sections to avoid permuting the thread init/shutdown too much
|
||||
void RunJobTests()
|
||||
{
|
||||
// one job
|
||||
{
|
||||
bool flag = false;
|
||||
Threading::JobSystem::AddJob([&flag]() { flag = true; });
|
||||
|
||||
Threading::JobSystem::SyncAllJobs();
|
||||
|
||||
CHECK(flag);
|
||||
}
|
||||
|
||||
// many jobs
|
||||
{
|
||||
static const size_t numJobs = 5000;
|
||||
static const size_t numItems = 500;
|
||||
rdcarray<int> a[numJobs];
|
||||
|
||||
for(size_t j = 0; j < numJobs; j++)
|
||||
{
|
||||
a[j].reserve(numItems);
|
||||
for(size_t i = 0; i < numItems; i++)
|
||||
a[j].push_back(rand());
|
||||
|
||||
Threading::JobSystem::AddJob([&a, j]() { std::sort(a[j].begin(), a[j].end()); });
|
||||
}
|
||||
|
||||
Threading::JobSystem::SyncAllJobs();
|
||||
|
||||
for(size_t j = 0; j < numJobs; j++)
|
||||
CHECK(isSorted(a[j]));
|
||||
}
|
||||
|
||||
// one job and dependency
|
||||
{
|
||||
rdcarray<int> a;
|
||||
Threading::JobSystem::Job *first = Threading::JobSystem::AddJob([&a]() { a.push_back(1); });
|
||||
Threading::JobSystem::AddJob([&a]() { a.push_back(2); }, {first});
|
||||
|
||||
Threading::JobSystem::SyncAllJobs();
|
||||
|
||||
CHECK(a == rdcarray<int>({1, 2}));
|
||||
}
|
||||
|
||||
// long dependency chain
|
||||
{
|
||||
rdcarray<int> a;
|
||||
rdcarray<int> b;
|
||||
|
||||
rdcarray<Threading::JobSystem::Job *> parents;
|
||||
for(int i = 0; i < 100; i++)
|
||||
{
|
||||
parents = {Threading::JobSystem::AddJob([&a, i]() { a.push_back(i); }, parents)};
|
||||
|
||||
b.push_back(i);
|
||||
}
|
||||
|
||||
Threading::JobSystem::SyncAllJobs();
|
||||
|
||||
CHECK(a == b);
|
||||
}
|
||||
|
||||
// multiple dependency chains
|
||||
{
|
||||
static const size_t numChains = 50;
|
||||
rdcarray<int> a[numChains];
|
||||
rdcarray<int> b[numChains];
|
||||
|
||||
rdcarray<Threading::JobSystem::Job *> parents[numChains];
|
||||
for(int i = 0; i < 100; i++)
|
||||
{
|
||||
for(size_t c = 0; c < numChains; c++)
|
||||
{
|
||||
parents[c] = {Threading::JobSystem::AddJob([&a, c, i]() { a[c].push_back(i); }, parents[c])};
|
||||
|
||||
b[c].push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
Threading::JobSystem::SyncAllJobs();
|
||||
|
||||
for(size_t c = 0; c < numChains; c++)
|
||||
CHECK(a[c] == b[c]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Check job system behaviour is correct with common thread counts", "[jobs]")
|
||||
{
|
||||
Threading::randomSleepRange = 10;
|
||||
Threading::randomSpinRange = 1000;
|
||||
uint32_t numThreads = GENERATE(1, 2, 14, 24);
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
RunJobTests();
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
|
||||
// start up and shut down again a couple of times to ensure that works as well
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
}
|
||||
|
||||
// since lock contention can get really bad with many threads, only do this test once
|
||||
TEST_CASE("Stress test job system with many threads", "[jobs][stress]")
|
||||
{
|
||||
Threading::randomSleepRange = 2;
|
||||
Threading::randomSpinRange = 100;
|
||||
uint32_t numThreads = 1000;
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
RunJobTests();
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
|
||||
// start up and shut down again a couple of times to ensure that works as well
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
|
||||
Threading::JobSystem::Init(numThreads);
|
||||
|
||||
Threading::JobSystem::Shutdown();
|
||||
}
|
||||
|
||||
#endif // ENABLED(ENABLE_UNIT_TESTS)
|
||||
@@ -533,6 +533,7 @@
|
||||
<ClCompile Include="common\common.cpp" />
|
||||
<ClCompile Include="common\dds_readwrite.cpp" />
|
||||
<ClCompile Include="common\jobsystem.cpp" />
|
||||
<ClCompile Include="common\jobsystem_tests.cpp" />
|
||||
<ClCompile Include="common\threading_tests.cpp" />
|
||||
<ClCompile Include="core\bit_flag_iterator_tests.cpp" />
|
||||
<ClCompile Include="core\gpu_address_range_tracker.cpp" />
|
||||
|
||||
@@ -965,6 +965,9 @@
|
||||
<ClCompile Include="common\jobsystem.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="common\jobsystem_tests.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="os\win32\comexport.def">
|
||||
|
||||
Reference in New Issue
Block a user