18-05-26 result
This commit is contained in:
@@ -45,17 +45,46 @@ struct PerfStats
|
||||
uint64_t frames = 0;
|
||||
uint64_t feedReadTicks = 0;
|
||||
uint64_t uploadDecodeTicks = 0;
|
||||
uint64_t stageCopyTicks = 0;
|
||||
uint64_t uploadRecordTicks = 0;
|
||||
uint64_t submitPresentTicks = 0;
|
||||
uint64_t idleDelayTicks = 0;
|
||||
uint64_t frameTicks = 0;
|
||||
};
|
||||
|
||||
struct FramePerfStats
|
||||
{
|
||||
uint64_t eventTicks = 0;
|
||||
uint64_t fenceWaitTicks = 0;
|
||||
uint64_t feedReadTicks = 0;
|
||||
uint64_t stageCopyTicks = 0;
|
||||
uint64_t maxStageCopyTicks = 0;
|
||||
uint64_t maxStageCopyBytes = 0;
|
||||
uint32_t maxStageCopyFeed = 0;
|
||||
uint32_t stageCopies = 0;
|
||||
uint32_t v210StageCopies = 0;
|
||||
uint64_t uploadRecordTicks = 0;
|
||||
uint64_t layoutTicks = 0;
|
||||
uint64_t imguiTicks = 0;
|
||||
uint64_t drawRecordTicks = 0;
|
||||
uint64_t acquireTicks = 0;
|
||||
uint64_t submitPresentTicks = 0;
|
||||
uint64_t idleDelayTicks = 0;
|
||||
};
|
||||
|
||||
struct FeedPerfStats
|
||||
{
|
||||
uint64_t updates = 0;
|
||||
uint64_t uploads = 0;
|
||||
uint64_t deferredUploads = 0;
|
||||
uint64_t repeats = 0;
|
||||
uint64_t skippedGrains = 0;
|
||||
uint64_t lastGrain = 0;
|
||||
uint64_t lastUploadTicks = 0;
|
||||
uint64_t uploadIntervalTicks = 0;
|
||||
uint64_t minUploadIntervalTicks = UINT64_MAX;
|
||||
uint64_t maxUploadIntervalTicks = 0;
|
||||
uint64_t uploadIntervals = 0;
|
||||
bool hasLastGrain = false;
|
||||
};
|
||||
|
||||
@@ -721,6 +750,11 @@ int main(int argc, char* argv[])
|
||||
std::vector<bool> v210FeedReady(feedCount);
|
||||
std::vector<uint64_t> uploadedVersions(feedCount);
|
||||
std::vector<bool> feedUploadNeeded(feedCount);
|
||||
std::vector<const VideoFrame*> pendingFrames(feedCount);
|
||||
std::vector<uint64_t> pendingVersions(feedCount);
|
||||
std::vector<bool> pendingUploadNeeded(feedCount);
|
||||
std::vector<double> feedUploadCredits(feedCount, 1.0);
|
||||
uint64_t lastUploadPaceTicks = SDL_GetPerformanceCounter();
|
||||
|
||||
std::fill(
|
||||
uploadedVersions.begin(),
|
||||
@@ -1026,9 +1060,14 @@ int main(int argc, char* argv[])
|
||||
const Uint64 frameStartTicks = SDL_GetTicks();
|
||||
const uint64_t perfFrameStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
FramePerfStats framePerf;
|
||||
uint64_t perfSectionStartTicks = 0;
|
||||
|
||||
SDL_Event event;
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
@@ -1048,11 +1087,18 @@ int main(int argc, char* argv[])
|
||||
if (event.key.key == SDLK_ESCAPE)
|
||||
{
|
||||
g_running = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
framePerf.eventTicks +=
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
}
|
||||
|
||||
// ---- resize handling ----
|
||||
|
||||
if (framebufferResized)
|
||||
@@ -1124,7 +1170,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// ---- frame timing ----
|
||||
|
||||
uint64_t perfSectionStartTicks =
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
vkWaitForFences(
|
||||
@@ -1142,9 +1188,12 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.submitPresentTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.submitPresentTicks += elapsed;
|
||||
framePerf.fenceWaitTicks += elapsed;
|
||||
framePerf.submitPresentTicks += elapsed;
|
||||
}
|
||||
|
||||
++frameCounter;
|
||||
@@ -1178,6 +1227,47 @@ int main(int argc, char* argv[])
|
||||
feedUploadNeeded.end(),
|
||||
false
|
||||
);
|
||||
std::fill(
|
||||
pendingFrames.begin(),
|
||||
pendingFrames.end(),
|
||||
nullptr
|
||||
);
|
||||
std::fill(
|
||||
pendingUploadNeeded.begin(),
|
||||
pendingUploadNeeded.end(),
|
||||
false
|
||||
);
|
||||
|
||||
const uint64_t uploadPaceTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
const double uploadPaceDeltaSeconds =
|
||||
static_cast<double>(
|
||||
uploadPaceTicks - lastUploadPaceTicks) /
|
||||
static_cast<double>(perfFrequency);
|
||||
lastUploadPaceTicks = uploadPaceTicks;
|
||||
|
||||
if (config.paceUploads)
|
||||
{
|
||||
for (uint32_t i = 0; i < feedCount; ++i)
|
||||
{
|
||||
if (!feeds[i]->hasFrameRate())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const double rate =
|
||||
std::min(
|
||||
feeds[i]->frameRate(),
|
||||
static_cast<double>(config.fpsCap)
|
||||
);
|
||||
feedUploadCredits[i] =
|
||||
std::min(
|
||||
2.0,
|
||||
feedUploadCredits[i] +
|
||||
rate * uploadPaceDeltaSeconds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < feedCount; ++i)
|
||||
{
|
||||
@@ -1193,9 +1283,11 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.feedReadTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.feedReadTicks += elapsed;
|
||||
framePerf.feedReadTicks += elapsed;
|
||||
|
||||
if (uploadNeeded)
|
||||
{
|
||||
@@ -1231,10 +1323,55 @@ int main(int argc, char* argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
pendingFrames[i] = &frame;
|
||||
pendingVersions[i] = version;
|
||||
pendingUploadNeeded[i] = true;
|
||||
}
|
||||
|
||||
const uint32_t maxV210Uploads =
|
||||
config.maxV210UploadsPerFrame == 0
|
||||
? feedCount
|
||||
: config.maxV210UploadsPerFrame;
|
||||
uint32_t v210UploadsThisFrame = 0;
|
||||
const uint32_t uploadStart =
|
||||
feedCount == 0 ? 0 : frameCounter % feedCount;
|
||||
|
||||
for (uint32_t offset = 0; offset < feedCount; ++offset)
|
||||
{
|
||||
const uint32_t i =
|
||||
(uploadStart + offset) % feedCount;
|
||||
|
||||
if (!pendingUploadNeeded[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool isV210 = feeds[i]->hasV210();
|
||||
if (config.paceUploads &&
|
||||
isV210 &&
|
||||
feeds[i]->hasFrameRate() &&
|
||||
feedUploadCredits[i] < 1.0)
|
||||
{
|
||||
if (config.logPerf)
|
||||
{
|
||||
++feedPerfStats[i].deferredUploads;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isV210 && v210UploadsThisFrame >= maxV210Uploads)
|
||||
{
|
||||
if (config.logPerf)
|
||||
{
|
||||
++feedPerfStats[i].deferredUploads;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
if (feeds[i]->hasV210())
|
||||
if (isV210)
|
||||
{
|
||||
if (!v210FeedReady[i])
|
||||
{
|
||||
@@ -1284,7 +1421,7 @@ int main(int argc, char* argv[])
|
||||
else
|
||||
{
|
||||
copyFrameToFeedTextureStaging(
|
||||
frame,
|
||||
*pendingFrames[i],
|
||||
imageSize,
|
||||
feedTextures[i]
|
||||
);
|
||||
@@ -1292,17 +1429,79 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.uploadDecodeTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.stageCopyTicks += elapsed;
|
||||
perfStats.uploadDecodeTicks += elapsed;
|
||||
framePerf.stageCopyTicks += elapsed;
|
||||
++framePerf.stageCopies;
|
||||
if (isV210)
|
||||
{
|
||||
++framePerf.v210StageCopies;
|
||||
}
|
||||
if (elapsed > framePerf.maxStageCopyTicks)
|
||||
{
|
||||
framePerf.maxStageCopyTicks = elapsed;
|
||||
framePerf.maxStageCopyFeed = i + 1;
|
||||
framePerf.maxStageCopyBytes =
|
||||
isV210
|
||||
? static_cast<uint64_t>(
|
||||
feeds[i]->v210Stride()) *
|
||||
feeds[i]->v210Height()
|
||||
: static_cast<uint64_t>(imageSize);
|
||||
}
|
||||
}
|
||||
|
||||
uploadedVersions[i] = version;
|
||||
uploadedVersions[i] = pendingVersions[i];
|
||||
if (isV210)
|
||||
{
|
||||
++v210UploadsThisFrame;
|
||||
if (config.paceUploads &&
|
||||
feeds[i]->hasFrameRate())
|
||||
{
|
||||
feedUploadCredits[i] =
|
||||
std::max(
|
||||
0.0,
|
||||
feedUploadCredits[i] - 1.0
|
||||
);
|
||||
}
|
||||
}
|
||||
if (config.logPerf)
|
||||
{
|
||||
++feedPerfStats[i].uploads;
|
||||
|
||||
const uint64_t uploadTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
if (feedPerfStats[i].lastUploadTicks != 0)
|
||||
{
|
||||
const uint64_t interval =
|
||||
uploadTicks -
|
||||
feedPerfStats[i].lastUploadTicks;
|
||||
feedPerfStats[i].uploadIntervalTicks +=
|
||||
interval;
|
||||
feedPerfStats[i].minUploadIntervalTicks =
|
||||
std::min(
|
||||
feedPerfStats[i].minUploadIntervalTicks,
|
||||
interval
|
||||
);
|
||||
feedPerfStats[i].maxUploadIntervalTicks =
|
||||
std::max(
|
||||
feedPerfStats[i].maxUploadIntervalTicks,
|
||||
interval
|
||||
);
|
||||
++feedPerfStats[i].uploadIntervals;
|
||||
}
|
||||
feedPerfStats[i].lastUploadTicks = uploadTicks;
|
||||
}
|
||||
feedUploadNeeded[i] = true;
|
||||
}
|
||||
|
||||
// ---- update vertex UVs for aspect ratio ----
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
VkExtent2D swapExtent = swapchain.extent();
|
||||
const float gapX =
|
||||
2.0f * TILE_GAP_PIXELS /
|
||||
@@ -1349,8 +1548,18 @@ int main(int argc, char* argv[])
|
||||
static_cast<size_t>(vbSize)
|
||||
);
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
framePerf.layoutTicks +=
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
}
|
||||
|
||||
// ---- ImGui frame ----
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
@@ -1364,6 +1573,13 @@ int main(int argc, char* argv[])
|
||||
ImGui::Render();
|
||||
ImDrawData* imguiDrawData = ImGui::GetDrawData();
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
framePerf.imguiTicks +=
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
}
|
||||
|
||||
// ---- record upload commands ----
|
||||
|
||||
perfSectionStartTicks =
|
||||
@@ -1431,9 +1647,12 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.uploadDecodeTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.uploadRecordTicks += elapsed;
|
||||
perfStats.uploadDecodeTicks += elapsed;
|
||||
framePerf.uploadRecordTicks += elapsed;
|
||||
}
|
||||
|
||||
// ---- acquire swapchain image ----
|
||||
@@ -1453,6 +1672,13 @@ int main(int argc, char* argv[])
|
||||
&imageIndex
|
||||
);
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
framePerf.acquireTicks +=
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
}
|
||||
|
||||
if (acquireResult == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
std::cout
|
||||
@@ -1471,14 +1697,27 @@ int main(int argc, char* argv[])
|
||||
);
|
||||
}
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
recordDrawCmdBuf(
|
||||
drawCmdBufs[imageIndex],
|
||||
imageIndex,
|
||||
imguiDrawData
|
||||
);
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
framePerf.drawRecordTicks +=
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
}
|
||||
|
||||
// ---- submit ----
|
||||
|
||||
perfSectionStartTicks =
|
||||
SDL_GetPerformanceCounter();
|
||||
|
||||
VkPipelineStageFlags waitStage =
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
||||
@@ -1554,9 +1793,11 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.submitPresentTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.submitPresentTicks += elapsed;
|
||||
framePerf.submitPresentTicks += elapsed;
|
||||
}
|
||||
|
||||
const Uint64 frameElapsedTicks =
|
||||
@@ -1575,9 +1816,11 @@ int main(int argc, char* argv[])
|
||||
|
||||
if (config.logPerf)
|
||||
{
|
||||
perfStats.idleDelayTicks +=
|
||||
const uint64_t elapsed =
|
||||
SDL_GetPerformanceCounter() -
|
||||
perfSectionStartTicks;
|
||||
perfStats.idleDelayTicks += elapsed;
|
||||
framePerf.idleDelayTicks += elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1586,7 +1829,76 @@ int main(int argc, char* argv[])
|
||||
++perfStats.frames;
|
||||
|
||||
const uint64_t now = SDL_GetPerformanceCounter();
|
||||
perfStats.frameTicks += now - perfFrameStartTicks;
|
||||
const uint64_t currentFrameTicks =
|
||||
now - perfFrameStartTicks;
|
||||
perfStats.frameTicks += currentFrameTicks;
|
||||
|
||||
const double invMs =
|
||||
1000.0 /
|
||||
static_cast<double>(perfFrequency);
|
||||
|
||||
if (currentFrameTicks * invMs > 25.0)
|
||||
{
|
||||
const uint64_t accountedTicks =
|
||||
framePerf.eventTicks +
|
||||
framePerf.fenceWaitTicks +
|
||||
framePerf.feedReadTicks +
|
||||
framePerf.stageCopyTicks +
|
||||
framePerf.uploadRecordTicks +
|
||||
framePerf.layoutTicks +
|
||||
framePerf.imguiTicks +
|
||||
framePerf.drawRecordTicks +
|
||||
framePerf.acquireTicks +
|
||||
framePerf.submitPresentTicks +
|
||||
framePerf.idleDelayTicks;
|
||||
const uint64_t otherTicks =
|
||||
currentFrameTicks > accountedTicks
|
||||
? currentFrameTicks - accountedTicks
|
||||
: 0;
|
||||
|
||||
std::cout
|
||||
<< "SPIKE frame="
|
||||
<< (currentFrameTicks * invMs)
|
||||
<< "ms event="
|
||||
<< (framePerf.eventTicks * invMs)
|
||||
<< "ms fence="
|
||||
<< (framePerf.fenceWaitTicks * invMs)
|
||||
<< "ms feedRead="
|
||||
<< (framePerf.feedReadTicks * invMs)
|
||||
<< "ms stageCopy="
|
||||
<< (framePerf.stageCopyTicks * invMs)
|
||||
<< "ms stageCopies="
|
||||
<< framePerf.stageCopies
|
||||
<< " v210Copies="
|
||||
<< framePerf.v210StageCopies
|
||||
<< " maxCopy=f"
|
||||
<< framePerf.maxStageCopyFeed
|
||||
<< ":"
|
||||
<< (framePerf.maxStageCopyTicks * invMs)
|
||||
<< "ms/"
|
||||
<< (static_cast<double>(
|
||||
framePerf.maxStageCopyBytes) /
|
||||
(1024.0 * 1024.0))
|
||||
<< "MiB"
|
||||
<< " uploadRecord="
|
||||
<< (framePerf.uploadRecordTicks * invMs)
|
||||
<< "ms layout="
|
||||
<< (framePerf.layoutTicks * invMs)
|
||||
<< "ms imgui="
|
||||
<< (framePerf.imguiTicks * invMs)
|
||||
<< "ms drawRecord="
|
||||
<< (framePerf.drawRecordTicks * invMs)
|
||||
<< "ms acquire="
|
||||
<< (framePerf.acquireTicks * invMs)
|
||||
<< "ms submitPresent="
|
||||
<< (framePerf.submitPresentTicks * invMs)
|
||||
<< "ms idleDelay="
|
||||
<< (framePerf.idleDelayTicks * invMs)
|
||||
<< "ms other="
|
||||
<< (otherTicks * invMs)
|
||||
<< "ms"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
const uint64_t elapsedTicks = now - lastPerfLogTicks;
|
||||
|
||||
@@ -1595,9 +1907,6 @@ int main(int argc, char* argv[])
|
||||
const double elapsedSeconds =
|
||||
static_cast<double>(elapsedTicks) /
|
||||
static_cast<double>(perfFrequency);
|
||||
const double invMs =
|
||||
1000.0 /
|
||||
static_cast<double>(perfFrequency);
|
||||
const double frames =
|
||||
static_cast<double>(perfStats.frames);
|
||||
|
||||
@@ -1607,6 +1916,10 @@ int main(int argc, char* argv[])
|
||||
<< (perfStats.feedReadTicks * invMs / frames)
|
||||
<< "ms uploadDecode="
|
||||
<< (perfStats.uploadDecodeTicks * invMs / frames)
|
||||
<< "ms stageCopy="
|
||||
<< (perfStats.stageCopyTicks * invMs / frames)
|
||||
<< "ms uploadRecord="
|
||||
<< (perfStats.uploadRecordTicks * invMs / frames)
|
||||
<< "ms submitPresent="
|
||||
<< (perfStats.submitPresentTicks * invMs / frames)
|
||||
<< "ms idleDelay="
|
||||
@@ -1625,6 +1938,8 @@ int main(int argc, char* argv[])
|
||||
<< feedRuntimeStatusName(
|
||||
feeds[i]->status())
|
||||
<< ":upd=" << feedPerfStats[i].updates
|
||||
<< ",upl=" << feedPerfStats[i].uploads
|
||||
<< ",def=" << feedPerfStats[i].deferredUploads
|
||||
<< ",rep=" << feedPerfStats[i].repeats;
|
||||
|
||||
if (feedPerfStats[i].hasLastGrain)
|
||||
@@ -1638,6 +1953,44 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "JITTER";
|
||||
for (uint32_t i = 0; i < feedCount; ++i)
|
||||
{
|
||||
std::cout << " f" << (i + 1)
|
||||
<< ":upl=" << feedPerfStats[i].uploads;
|
||||
|
||||
if (feedPerfStats[i].uploadIntervals > 0)
|
||||
{
|
||||
const double avgMs =
|
||||
feedPerfStats[i].uploadIntervalTicks *
|
||||
invMs /
|
||||
static_cast<double>(
|
||||
feedPerfStats[i].uploadIntervals);
|
||||
const double minMs =
|
||||
feedPerfStats[i].minUploadIntervalTicks *
|
||||
invMs;
|
||||
const double maxMs =
|
||||
feedPerfStats[i].maxUploadIntervalTicks *
|
||||
invMs;
|
||||
|
||||
std::cout
|
||||
<< ",avg=" << avgMs
|
||||
<< "ms,min=" << minMs
|
||||
<< "ms,max=" << maxMs
|
||||
<< "ms";
|
||||
}
|
||||
|
||||
if (feeds[i]->hasFrameRate() &&
|
||||
feeds[i]->frameRate() > 0.0)
|
||||
{
|
||||
std::cout
|
||||
<< ",exp="
|
||||
<< (1000.0 / feeds[i]->frameRate())
|
||||
<< "ms";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
ThreadCpuSamples currentThreadCpuSamples =
|
||||
collectThreadCpuSamples();
|
||||
printThreadCpuPerf(
|
||||
|
||||
Reference in New Issue
Block a user