1
0
mirror of synced 2026-01-23 18:46:33 +00:00
2020-09-09 15:11:45 -07:00

307 lines
6.9 KiB
C++

#ifndef __PERF_TOOLS_H__
#define __PERF_TOOLS_H__
#include "utils.h"
#include "cray_types.h"
#include "cray_logger.h"
#include <vector>
#include <iostream>
using namespace std;
namespace PerfTools {
class Resource_i {
public:
virtual void Tick(uint32_t aAmount=1) = 0;
};
class Pipeline_c {
public:
Pipeline_c(): mStallCount(0), mTickCount(0) {}
void Tick(uint32_t aAmount=1);
void Stall(uint32_t aAmount);
void Print(ostream &aStream) const;
void AddResource(Resource_i *aResource);
protected:
uint32_t mStallCount;
uint32_t mTickCount;
vector<Resource_i*> mResources;
};
inline ostream & operator << (ostream &aStream, const Pipeline_c &aItem) {
if (!aStream.good()) return aStream;
aItem.Print(aStream);
return aStream;
}
class MemoryModel_c: public Resource_i {
public:
MemoryModel_c(
uint32_t aReadLatency,
uint32_t aWriteLatency,
uint32_t aTagLatency,
uint32_t aCacheSize,
uint32_t aLineSize,
uint32_t aNumWays,
uint32_t aBurstReadRate,
bool aInvalidateOnWrite,
bool aAllocateOnWrite,
bool aWriteBack,
Pipeline_c &aParent
):
mReadLatency(aReadLatency),
mWriteLatency(aWriteLatency),
mTagLatency(aTagLatency),
mCacheSize(aCacheSize),
mLineSize(aLineSize),
mNumWays(aNumWays),
mUncachedReadCount(0),
mMissCount(0),
mReadCount(0),
mWriteCount(0),
mReadDelayCount(0),
mWriteDelayCount(0),
mWriteInvalidateCount(0),
mInvalidateOnWrite(aInvalidateOnWrite),
mAllocateOnWrite(aAllocateOnWrite),
mBurstReadRate(aBurstReadRate),
mWriteBack(aWriteBack),
mEvictionCount(0),
mWriteAllocateCount(0),
mParent(aParent)
{
mTagSize = aNumWays == 0 ? 0 : aCacheSize/aNumWays/aLineSize;
CRAY_ASSERT(!(mInvalidateOnWrite && mAllocateOnWrite));
CRAY_ASSERT(!(mInvalidateOnWrite && mWriteBack));
mParent.AddResource(this);
for(mLineSizeBits = 0; mLineSizeBits < 32; ++mLineSizeBits) {
if ((1UL << mLineSizeBits) >= mLineSize) break;
}
for(mTagSizeBits = 0; mTagSizeBits < 32; ++mTagSizeBits) {
if ((1UL << mTagSizeBits) >= mTagSize) break;
}
mTag.resize(mNumWays);
for(uint32_t Way=0;Way<mNumWays;++Way) {
mTag[Way].resize(mTagSize);
}
}
virtual void Tick(uint32_t aAmount=1) override;
uint32_t ReadLatency() { ++mUncachedReadCount; mReadDelayCount += mReadLatency; return mReadLatency; }
// uint32_t WriteLatency() { return mWriteLatency; }
uint32_t ReadLatency(uint32_t aAddr);
uint32_t WriteLatency(uint32_t aAddr);
void Print(ostream &aStream) const;
protected:
uint32_t GetTagIdx(uint32_t aAddr) { return (aAddr >> mLineSizeBits) & ((1 << mTagSizeBits) - 1); }
uint32_t GetTagAddr(uint32_t aAddr) { return aAddr >> mLineSizeBits >> mTagSizeBits; }
struct TagEntry_s {
bool Valid;
bool Dirty;
uint32_t Addr;
uint32_t TimeStamp;
TagEntry_s(): Valid(false) {}
};
typedef vector<TagEntry_s> WayTag_t;
typedef vector<WayTag_t> Tag_t;
Tag_t mTag;
uint32_t mReadLatency;
uint32_t mWriteLatency;
uint32_t mTagLatency;
uint32_t mCacheSize;
uint32_t mLineSize;
uint32_t mLineSizeBits;
uint32_t mTagSize;
uint32_t mTagSizeBits;
uint32_t mNumWays;
bool mInvalidateOnWrite;
bool mAllocateOnWrite;
bool mWriteBack;
uint32_t mBurstReadRate;
uint32_t mUncachedReadCount;
uint32_t mMissCount;
uint32_t mReadCount;
uint32_t mWriteCount;
uint32_t mReadDelayCount;
uint32_t mWriteDelayCount;
uint32_t mWriteInvalidateCount;
uint32_t mWriteAllocateCount;
uint32_t mEvictionCount;
Pipeline_c &mParent;
};
inline ostream & operator << (ostream &aStream, const MemoryModel_c &aItem) {
if (!aStream.good()) return aStream;
aItem.Print(aStream);
return aStream;
}
class InstFetch_c: public Resource_i {
public:
InstFetch_c(uint32_t aPrefetchBufferSize, Pipeline_c &aParent, MemoryModel_c &aMemoryModel):
mPrefetchBufferSize(aPrefetchBufferSize),
mPrefetchAmount(0),
mPostExecAmount(0),
mParent(aParent),
mInternalStall(false),
mFetchCount(0),
mShortJumpCount(0),
mOutOfBufferShortJumpCount(0),
mLongJumpCount(0),
mInterruptCount(0),
mStallCount(0),
mTargetCallStallCount(0),
mCurrentBasicBlockLength(0),
mInstructionFetches(0),
mMemoryModel(aMemoryModel)
{
mParent.AddResource(this);
}
virtual void Tick(uint32_t aAmount=1) override;
void Fetch(bool aHidden = false);
void ExtraFetch(bool aHidden = false);
void TargetCalcStall(uint32_t aAmount);
void ShortJump(int32_t aOffset);
void LongJump();
void Interrupt();
void Print(ostream &aStream) const;
protected:
uint32_t mPrefetchBufferSize;
uint32_t mPrefetchAmount;
uint32_t mPostExecAmount;
Pipeline_c &mParent;
bool mInternalStall;
uint32_t mFetchCount;
uint32_t mShortJumpCount;
uint32_t mOutOfBufferShortJumpCount;
uint32_t mLongJumpCount;
uint32_t mInterruptCount;
uint32_t mStallCount;
uint32_t mTargetCallStallCount;
uint32_t mInstructionFetches;
MemoryModel_c &mMemoryModel;
uint32_t mCurrentBasicBlockLength;
vector<uint32_t> mBasicBlockLengths;
};
inline ostream & operator << (ostream &aStream, const InstFetch_c &aItem) {
if (!aStream.good()) return aStream;
aItem.Print(aStream);
return aStream;
}
class ComputeResource_c: public Resource_i {
public:
ComputeResource_c(const string &aName, size_t aMaxPipelineLength, Pipeline_c &aParent): mName(aName), mParent(aParent), mStallCount(0), mUseCount(0) {
mUseMap.resize(aMaxPipelineLength);
mParent.AddResource(this);
}
virtual void Tick(uint32_t aAmount=1) override;
void Use(uint32_t aTimeInFuture, uint32_t aDuration = 1);
void Print(ostream &aStream) const;
protected:
string mName;
vector<bool> mUseMap;
Pipeline_c &mParent;
size_t mStallCount;
size_t mUseCount;
};
inline ostream & operator << (ostream &aStream, const ComputeResource_c &aItem) {
if (!aStream.good()) return aStream;
aItem.Print(aStream);
return aStream;
}
class StorageResource_c: public Resource_i {
public:
StorageResource_c(const string &aName, Pipeline_c &aParent):
mName(aName),
mNextRead(0),
mNextWrite(0),
mParent(aParent),
mStallCount(0),
mReadCount(0),
mWriteCount(0),
mReadAfterReadCount(0),
mReadAfterWriteCount(0),
mWriteAfterReadCount(0),
mWriteAfterWriteCount(0),
mReadAfterReadStallCount(0),
mReadAfterWriteStallCount(0),
mWriteAfterReadStallCount(0),
mWriteAfterWriteStallCount(0)
{
mParent.AddResource(this);
}
virtual void Tick(uint32_t aAmount=1) override;
void Read(uint32_t aTimeInFuture);
void Write(uint32_t aTimeInFuture);
void Print(ostream &aStream) const;
protected:
string mName;
uint32_t mNextRead;
uint32_t mNextWrite;
Pipeline_c &mParent;
size_t mStallCount;
size_t mReadCount;
size_t mWriteCount;
size_t mReadAfterReadCount;
size_t mReadAfterWriteCount;
size_t mWriteAfterReadCount;
size_t mWriteAfterWriteCount;
size_t mReadAfterReadStallCount;
size_t mReadAfterWriteStallCount;
size_t mWriteAfterReadStallCount;
size_t mWriteAfterWriteStallCount;
};
inline ostream & operator << (ostream &aStream, const StorageResource_c &aItem) {
if (!aStream.good()) return aStream;
aItem.Print(aStream);
return aStream;
}
} // namespace PerfToos
#endif // __PERF_TOOLS_H__