Reece Wilson
7be2d3fbdc
[+] AuNet::ISocketStats [+] AuNet::ISocketChannel::GetRecvStats() [+] AuNet::ISocketChannel::GetSendStats() [+] AuIO::IOProcessor::RunTickEx(AuUInt32 dwTimeout) [*] Refactor clock APIs [+] Documentation in headers [+] AuIO::IIOPipeWork::GetStartTickMS() [+] AuIO::IIOPipeWork::GetLastTickMS() [+] AuIO::IIOPipeWork::GetPredictedThroughput() [+] AuIO::IIOPipeWork::GetBytesProcessed()
137 lines
3.4 KiB
Plaintext
137 lines
3.4 KiB
Plaintext
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: ThroughputCalculator.hpp
|
|
Date: 2022-12-06
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::Utility
|
|
{
|
|
struct ThroughputCalculator
|
|
{
|
|
// call me arbitrarily
|
|
double inline OnUpdate(AuUInt uUnit)
|
|
{
|
|
AU_LOCK_GUARD(this->lock);
|
|
|
|
OnTick(uUnit);
|
|
return this->dCurFreq;
|
|
}
|
|
|
|
|
|
// then call me arbitrarily:
|
|
double inline GetEstimatedHertz()
|
|
{
|
|
AU_LOCK_GUARD(this->lock);
|
|
|
|
auto uNow = Aurora::Time::SteadyClockNS();
|
|
auto uDelta = uNow - this->uLast;
|
|
|
|
// we cannot do anything on frame zero
|
|
if (!this->dCurFreq)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return this->dCurFreq;
|
|
}
|
|
|
|
AuUInt inline GetTotalStats()
|
|
{
|
|
return this->uTotalLifetime;
|
|
}
|
|
|
|
|
|
AuInt64 inline GetLastFrameTimeWall()
|
|
{
|
|
return this->uLastWall;
|
|
}
|
|
|
|
private:
|
|
|
|
void inline OnTick(AuUInt64 uUnit)
|
|
{
|
|
struct EntryTable
|
|
{
|
|
AuUInt32 uBits {};
|
|
AuUInt32 uTimeDelta {};
|
|
};
|
|
|
|
auto uNow = Aurora::Time::SteadyClockNS();
|
|
auto uDelta = uNow - this->uLast;
|
|
|
|
AuMemmove(uVecTable + 1, uVecTable, sizeof(uVecTable) - sizeof(*uVecTable));
|
|
|
|
auto pTable = ((EntryTable *)uVecTable);
|
|
bool bFirst = !this->uLast;
|
|
this->uLast = uNow;
|
|
if (bFirst)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->uLastWall = Aurora::Time::CurrentClockMS();
|
|
|
|
static const auto kOneSecond = AuMSToNS<AuUInt64>(AuSToMS<AuUInt64>(1));
|
|
|
|
|
|
pTable[0].uBits = (AuUInt32)uUnit;
|
|
pTable[0].uTimeDelta = (AuUInt32)(uDelta / 1000ull);
|
|
if (!pTable[0].uTimeDelta)
|
|
{
|
|
pTable[0].uTimeDelta = 1;
|
|
}
|
|
if (uVecSize < 10)
|
|
{
|
|
uVecSize++;
|
|
}
|
|
|
|
AuLogDbg("Added: {} {}", pTable[0].uBits, pTable[0].uTimeDelta * 1000ull);
|
|
|
|
double dTotal {};
|
|
double dTotalBits {};
|
|
double dTotalTime {};
|
|
double dSamples {};
|
|
|
|
for (AU_ITR_N(i, uVecSize))
|
|
{
|
|
if (!pTable[i].uTimeDelta)
|
|
{
|
|
pTable[i].uTimeDelta = 1;
|
|
}
|
|
|
|
double dDeltaSeconds = ((double)((AuUInt64)pTable[i].uTimeDelta * 1000ull) / (double)kOneSecond);
|
|
|
|
dTotalBits += pTable[i].uBits;
|
|
dTotalTime += dDeltaSeconds;
|
|
|
|
dTotal += (double)pTable[i].uBits / dDeltaSeconds;
|
|
|
|
dSamples++;
|
|
}
|
|
|
|
AuLogDbg("{}/{} ({})", dTotal, dSamples, uVecSize);
|
|
this->dCurFreq = dTotal / dSamples;
|
|
|
|
double a = dTotalBits / dTotalTime;
|
|
//if (this->dCurFreq > a)
|
|
//{
|
|
//}
|
|
//this->dCurFreq = AuMin(a, this->dCurFreq);
|
|
}
|
|
|
|
AuUInt8 uVecSize {};
|
|
AuUInt64 uVecTable[10];
|
|
|
|
AuThreadPrimitives::SpinLock lock;
|
|
|
|
AuUInt64 uLast {};
|
|
|
|
AuUInt uTotalLifetime {};
|
|
AuInt64 uLastWall {};
|
|
|
|
double dCurFreq {};
|
|
};
|
|
} |