Merge pull request #4187 from Scramblrrrr/codex/cpu-copy-profile-spans

fix(agc): profile completed CPU copies with their actual spans
This commit is contained in:
Dean 2026-10-13 17:54:30 +13:00 committed by GitHub
commit 3cfb915cf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 36 additions and 30 deletions

View File

@ -3088,35 +3088,12 @@ void GuestBufferMemory::copyRegion(Region& region, bool addressable) {
static const bool profile = std::getenv("APS5_PROFILE_DRAW") != nullptr;
const auto bytes = region.end - region.begin;
const auto usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | (addressable ? VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT : 0u);
if (profile) {
// Why the region is copied rather than bound in place, totalled every 1000 uploads (under a
// mutex: prepare stages of several builds copy at once).
static std::mutex reasonsMutex;
static std::uint64_t uploads = 0, noImport = 0, noImportBytes = 0, misaligned = 0, misalignedBytes = 0, snapshotOnly = 0, snapshotBytes = 0;
static std::map<std::uint64_t, std::pair<std::uint64_t, std::uint64_t>> outside;
bool inImport = false;
if (context.hostImportAlignment != 0) {
auto& state = Imports();
std::lock_guard lock(state.mutex);
inImport = findImport(state, region.begin, region.end) != nullptr;
}
std::lock_guard lock(reasonsMutex);
if (!region.hostBacked && !region.writable) { ++snapshotOnly; snapshotBytes += bytes; }
else if (inImport) { ++misaligned; misalignedBytes += bytes; }
else {
++noImport;
noImportBytes += bytes;
auto& bucket = outside[region.begin >> 28u];
++bucket.first;
bucket.second += bytes;
}
if (++uploads % 1000 == 0) {
// 'misaligned in imports' are the ones the GPU did not copy: over APS5_GPU_COPY_MAX_KIB,
// sparse, APS5_CPU_COPIES, no recorder, or an import gone by UploadFinish.
AgcDriver::ProfilePrint_nid_no_patch("[buffers] %llu copied regions on the CPU: %llu snapshots (%.0f MiB), %llu misaligned in imports (%.0f MiB), %llu outside imports (%.0f MiB):", static_cast<unsigned long long>(uploads), static_cast<unsigned long long>(snapshotOnly), snapshotBytes / 1048576.0, static_cast<unsigned long long>(misaligned), misalignedBytes / 1048576.0, static_cast<unsigned long long>(noImport), noImportBytes / 1048576.0);
for (const auto& [granule, counts] : outside) AgcDriver::ProfilePrint_nid_no_patch(" 0x%llx0000000:%llu/%.0fMiB", static_cast<unsigned long long>(granule), static_cast<unsigned long long>(counts.first), counts.second / 1048576.0);
AgcDriver::ProfilePrint_nid_no_patch("\n");
}
std::uint64_t readBytes = 0;
bool inImport = false;
if (profile && context.hostImportAlignment != 0) {
auto& state = Imports();
std::lock_guard lock(state.mutex);
inImport = findImport(state, region.begin, region.end) != nullptr;
}
const auto allocateStart = std::chrono::steady_clock::now();
if (region.sparse && region.buffer == nullptr && (region.hostBacked || region.writable)) {
@ -3140,6 +3117,7 @@ void GuestBufferMemory::copyRegion(Region& region, bool addressable) {
const bool written = region.writable && WritesOverlap(region.begin, static_cast<std::size_t>(bytes));
if (!region.sparse) {
GuestMemory::Read(region.begin, region.buffer->Bytes());
readBytes += region.buffer->Bytes().size();
if (written) region.uploaded.assign(region.buffer->Bytes().begin(), region.buffer->Bytes().end());
} else {
// `uploaded` holds the backed pieces back to back.
@ -3150,15 +3128,43 @@ void GuestBufferMemory::copyRegion(Region& region, bool addressable) {
if (at > cursor) std::memset(target.data() + cursor, 0, at - cursor);
const auto piece = target.subspan(at, static_cast<std::size_t>(last - first));
GuestMemory::Read(first, piece);
readBytes += piece.size();
if (written) region.uploaded.insert(region.uploaded.end(), piece.begin(), piece.end());
cursor = at + piece.size();
}
if (cursor < target.size()) std::memset(target.data() + cursor, 0, target.size() - cursor);
}
}
else std::memcpy(region.buffer->Bytes().data(), region.snapshot.data(), region.snapshot.size());
else {
std::memcpy(region.buffer->Bytes().data(), region.snapshot.data(), region.snapshot.size());
readBytes += region.snapshot.size();
}
region.snapshot.clear();
if (profile) readUs.fetch_add(microsecondsSince(readStart), std::memory_order_relaxed);
if (profile) {
static std::mutex reasonsMutex;
static std::uint64_t uploads = 0, noImport = 0, noImportBytes = 0, misaligned = 0, misalignedBytes = 0, snapshotOnly = 0, snapshotBytes = 0;
static std::uint64_t logicalBytes = 0, readTotalBytes = 0;
static std::map<std::uint64_t, std::pair<std::uint64_t, std::uint64_t>> outside;
std::lock_guard lock(reasonsMutex);
const auto bufferBytes = region.buffer->Bytes().size();
logicalBytes += bytes;
readTotalBytes += readBytes;
if (!region.hostBacked && !region.writable) { ++snapshotOnly; snapshotBytes += bufferBytes; }
else if (inImport) { ++misaligned; misalignedBytes += bufferBytes; }
else {
++noImport;
noImportBytes += bufferBytes;
auto& bucket = outside[region.begin >> 28u];
++bucket.first;
bucket.second += bufferBytes;
}
if (++uploads % 1000 == 0) {
AgcDriver::ProfilePrint_nid_no_patch("[buffers] %llu completed CPU-copy operations: logical spans %.0f MiB, buffer spans %.0f MiB, bytes read %.0f MiB; %llu snapshots (%.0f MiB), %llu misaligned in imports (%.0f MiB), %llu outside imports (%.0f MiB):", static_cast<unsigned long long>(uploads), logicalBytes / 1048576.0, (snapshotBytes + misalignedBytes + noImportBytes) / 1048576.0, readTotalBytes / 1048576.0, static_cast<unsigned long long>(snapshotOnly), snapshotBytes / 1048576.0, static_cast<unsigned long long>(misaligned), misalignedBytes / 1048576.0, static_cast<unsigned long long>(noImport), noImportBytes / 1048576.0);
for (const auto& [granule, counts] : outside) AgcDriver::ProfilePrint_nid_no_patch(" 0x%llx0000000:%llu/%.0fMiB", static_cast<unsigned long long>(granule), static_cast<unsigned long long>(counts.first), counts.second / 1048576.0);
AgcDriver::ProfilePrint_nid_no_patch("\n");
}
}
}
void GuestBufferMemory::recordGpuCopies(std::span<Region* const> copies, bool addressable) {