void recordType(TypeProfileKey key, DataType dt) { if (!profiles) return; if (!isProfileRequest()) return; assert(dt != KindOfUninit); // Normalize strings to KindOfString. if (dt == KindOfStaticString) dt = KindOfString; TRACE(1, "recordType lookup: %s -> %d\n", key.m_name->data(), dt); ValueProfile *prof = keyToVP(key, KeyToVPMode::Write); if (prof->m_totalSamples != kMaxCounter) { prof->m_totalSamples++; // NB: we can't quite assert that we have fewer than kMaxCounter samples, // because other threads are updating this structure without locks. int dtIndex = getDataTypeIndex(dt); if (prof->m_samples[dtIndex] < kMaxCounter) { prof->m_samples[dtIndex]++; } } ONTRACE(2, prof->dump()); }
std::pair<DataType, double> predictType(const TypeProfileKey& key) { static const std::pair<DataType, double> kNullPred = std::make_pair(KindOfUninit, 0.0); if (!profiles) return kNullPred; const ValueProfile *prof = keyToVP(key, Read); if (!prof) return kNullPred; double total = 0.0; for (int i = 0; i < MaxNumDataTypes; ++i) total += prof->m_samples[i]; double maxProb = 0.0; DataType pred = KindOfUninit; // If we have fewer than kMinInstances predictions, consider it too // little data to be actionable. if (total >= kMinInstances) for (int i = 0; i < MaxNumDataTypes; ++i) { double prob = (1.0 * prof->m_samples[i]) / total; if (prob > maxProb) { maxProb = prob; pred = (DataType)i; } if (prob == 1.0) break; } return std::make_pair(pred, maxProb); }
PredVal predictType(TypeProfileKey key) { PredVal kNullPred = std::make_pair(KindOfUninit, 0.0); if (!profiles) return kNullPred; const ValueProfile *prof = keyToVP(key, KeyToVPMode::Read); if (!prof) { TRACE(2, "predictType lookup: %s -> MISS\n", key.m_name->data()); Stats::inc(Stats::TypePred_Miss); return kNullPred; } double total = prof->m_totalSamples; if (total < kMinInstances) { Stats::inc(Stats::TypePred_MissTooFew); TRACE(2, "TypePred: hit %s but too few samples numSamples %d\n", key.m_name->data(), prof->m_totalSamples); return kNullPred; } double maxProb = 0.0; DataType pred = KindOfUninit; // If we have fewer than kMinInstances predictions, consider it too // little data to be actionable. for (int i = 0; i < kNumDataTypes; ++i) { double prob = (1.0 * prof->m_samples[i]) / total; if (prob > maxProb) { maxProb = prob; pred = getDataTypeValue(i); } if (prob >= 1.0) break; } Stats::inc(Stats::TypePred_Hit, maxProb >= 1.0); Stats::inc(Stats::TypePred_MissTooWeak, maxProb < 1.0); TRACE(2, "TypePred: hit %s numSamples %d pred %d prob %g\n", key.m_name->data(), prof->m_totalSamples, pred, maxProb); // Probabilities over 1.0 are possible due to racy updates. if (maxProb > 1.0) maxProb = 1.0; return std::make_pair(pred, maxProb); }
void recordType(const TypeProfileKey& key, DataType dt) { if (!profiles) return; ValueProfile *prof = keyToVP(key, Write); bump8(prof->m_samples[dt]); bump8(prof->m_totalSamples); }