perf(agc): write each skip report in one call and cap its request dumps
mingw's fprintf writes an unbuffered stderr a character at a time: a title skipping many draws spent seconds per frame printing 17 KB RecompileRequest dumps (GTA V ran at 0.1 fps). Reports are built into one string and written once; dumps stop after 8 per reason (APS5_SKIP_REQUEST_DUMPS, -1 for all). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
75a8668b5e
commit
8cf2f65806
|
|
@ -1640,15 +1640,47 @@ private:
|
|||
}
|
||||
|
||||
// A draw or dispatch the translator cannot handle is skipped so the rest of the frame still runs;
|
||||
// each distinct failure is reported once.
|
||||
static void reportSkip(const char* kind, const std::string& what) {
|
||||
static std::mutex reportedMutex;
|
||||
static std::set<std::string> reported;
|
||||
std::lock_guard lock(reportedMutex);
|
||||
static std::set<std::size_t> reported;
|
||||
static std::map<std::string, int> requestDumps;
|
||||
// APS5_TRACE_SKIPS reports every skip (shortened), not only the first per reason.
|
||||
static const bool traceSkips = std::getenv("APS5_TRACE_SKIPS") != nullptr;
|
||||
if (reported.insert(what).second) std::fprintf(stderr, "[gpu] skipped %s: %s\n", kind, what.c_str());
|
||||
else if (traceSkips) std::fprintf(stderr, "[gpu] skipped %s again: %.100s\n", kind, what.c_str());
|
||||
static const int dumpLimit = [] { const char* text = std::getenv("APS5_SKIP_REQUEST_DUMPS"); return text ? std::atoi(text) : 8; }();
|
||||
static constexpr std::string_view marker = "\nRecompileRequest:\n";
|
||||
std::lock_guard lock(reportedMutex);
|
||||
std::string line;
|
||||
static bool announced = false;
|
||||
if (!announced) {
|
||||
announced = true;
|
||||
char text[160];
|
||||
std::snprintf(text, sizeof(text), "[gpu] skip reports: one write each, RecompileRequest dumps capped at %d per reason (APS5_SKIP_REQUEST_DUMPS)\n", dumpLimit);
|
||||
line = text;
|
||||
}
|
||||
const std::string prefix = "[gpu] skipped " + std::string(kind);
|
||||
if (reported.insert(std::hash<std::string>{}(what)).second) {
|
||||
const auto request = what.find(marker);
|
||||
if (request == std::string::npos) {
|
||||
line += prefix + ": " + what + "\n";
|
||||
} else {
|
||||
const auto reason = what.substr(0, request);
|
||||
const auto suffix = what.find(' ', request + marker.size());
|
||||
auto& dumps = requestDumps[reason];
|
||||
if (dumpLimit < 0 || dumps < dumpLimit) {
|
||||
++dumps;
|
||||
line += prefix + ": " + what + "\n";
|
||||
} else {
|
||||
if (dumps == dumpLimit) {
|
||||
++dumps;
|
||||
line += prefix + ": further RecompileRequest dumps for \"" + reason + "\" are left out\n";
|
||||
}
|
||||
line += prefix + ": " + reason + " (request left out)" + (suffix == std::string::npos ? std::string() : what.substr(suffix)) + "\n";
|
||||
}
|
||||
}
|
||||
} else if (traceSkips) {
|
||||
line += prefix + " again: " + what.substr(0, 100) + "\n";
|
||||
}
|
||||
if (!line.empty()) std::fwrite(line.data(), 1, line.size(), stderr);
|
||||
}
|
||||
template <typename Work>
|
||||
void tolerate(const char* kind, Work&& work) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue