void loadProfData() { if (!profFileName.empty()) { loadPerfEvents(); } // The prof-counters are collected independently. for (TransID tid = 0; tid < NTRANS; tid++) { PerfEvent profCounters; profCounters.type = SPECIAL_PROF_COUNTERS; profCounters.count = g_transData->getTransCounter(tid); transPerfEvents.addEvent(tid, profCounters); } }
void loadPerfEvents() { FILE* profFile; profFile = fopen(profFileName.c_str(), "rt"); if (!profFile) { error("Error opening file " + profFileName); } char program[MAX_SYM_LEN]; char eventCaption[MAX_SYM_LEN]; char line[2*MAX_SYM_LEN]; TCA addr; uint32_t tcSamples[NUM_EVENT_TYPES]; uint32_t hhvmSamples[NUM_EVENT_TYPES]; size_t numEntries = 0; PerfEventType eventType = NUM_EVENT_TYPES; // samplesPerKind[event][kind] uint32_t samplesPerKind[NUM_EVENT_TYPES][NumTransKinds]; uint32_t samplesPerTCRegion[NUM_EVENT_TYPES][TCRCount]; memset(tcSamples , 0, sizeof(tcSamples)); memset(hhvmSamples, 0, sizeof(hhvmSamples)); memset(samplesPerKind, 0, sizeof(samplesPerKind)); memset(samplesPerTCRegion, 0, sizeof(samplesPerTCRegion)); while (fgets(line, 2*MAX_SYM_LEN, profFile) != nullptr) { always_assert(sscanf(line, "%s %s %lu", program, eventCaption, &numEntries) == 3); always_assert(numEntries); std::vector<std::pair<TCA,std::string>> entries; for (size_t i = 0; i < numEntries; i++) { fscanf(profFile, "%p %s\n", &addr, line); entries.push_back(std::pair<TCA,std::string>(addr, line)); } if (strncmp(program, "hhvm", 4) == 0) { eventType = perfScriptOutputToEventType(eventCaption); if (eventType == NUM_EVENT_TYPES) { snprintf(errMsgBuff, MAX_SYM_LEN, "loadProfData: invalid event caption '%s'", eventCaption); error(errMsgBuff); } hhvmSamples[eventType]++; size_t selIdx = 0; addr = entries[0].first; if (inclusiveStats) { for (size_t i = 0; i < entries.size(); i++) { if (g_transData->isAddrInSomeTrans(entries[i].first)) { addr = entries[i].first; selIdx = i; break; } } } if (!(minAddr <= addr && addr <= maxAddr)) continue; if (!g_transData->isAddrInSomeTrans(addr)) continue; TransID transId = g_transData->getTransContaining(addr); always_assert(transId != INVALID_ID); tcSamples[eventType]++; const TransRec* trec = g_transData->getTransRec(transId); TransKind kind = trec->kind; samplesPerKind[eventType][static_cast<uint32_t>(kind)]++; TCRegion region = transCode->findTCRegionContaining(addr); always_assert(region != TCRCount); samplesPerTCRegion[eventType][region]++; std::vector<std::string> stackTrace; if (verboseStats) { for (size_t i = 0; i < selIdx; i++) { if (!strcmp(entries[i].second.c_str(), "[unknown]")) { // Append the address to disambiguate. entries[i].second += std::string("@") + toString((void*)entries[i].first); } stackTrace.push_back(entries[i].second); } reverse(stackTrace.begin(), stackTrace.end()); } if (selIdx) addr--; tcaPerfEvents.addEvent(addr, (PerfEvent) { eventType, 1 }, stackTrace); } } AddrToTransMapper transMapper(g_transData); transPerfEvents = tcaPerfEvents.mapTo(transMapper); printf("# Number of hhvm samples read (%% in TC) from file %s\n", profFileName.c_str()); for (size_t i = 0; i < NUM_EVENT_TYPES; i++) { if (!hhvmSamples[i]) continue; printf("# %-19s TOTAL: %10u (%u in TC = %5.2lf%%)\n", eventTypeToCommandLineArgument((PerfEventType)i), hhvmSamples[i], tcSamples[i], 100.0 * tcSamples[i] / hhvmSamples[i]); for (size_t j = 0; j < NumTransKinds; ++j) { auto ct = samplesPerKind[i][j]; if (!ct) continue; std::string kind = show(static_cast<TransKind>(j)); printf("# %26s: %-8u (%5.2lf%%)\n", kind.c_str(), ct, 100.0 * ct / tcSamples[i]); } printf("#\n"); } printf("\n"); // print per-TCRegion information // header printf("# TCRegion "); for (size_t i = 0; i < NUM_EVENT_TYPES; i++) { printf("%17s ", eventTypeToCommandLineArgument((PerfEventType)i)); } printf("\n"); // HW events for each region for (size_t i = 0 ; i < TCRCount ; i++) { printf("# %8s ", tcRegionToString(static_cast<TCRegion>(i)).c_str()); for (size_t j = 0; j < NUM_EVENT_TYPES; j++) { auto ct = samplesPerTCRegion[j][i]; printf("%8u (%5.2lf%%) ", ct, ct ? (100.0 * ct / tcSamples[j]) : 0); } printf("\n"); } printf("#\n\n"); fclose(profFile); }