Добавлена папка source в CristalDiskMark
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
|
||||
namespace UnitTests { class CmdLineParserUnitTests; }
|
||||
|
||||
class CmdLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser();
|
||||
~CmdLineParser();
|
||||
|
||||
bool ParseCmdLine(const int argc, const char *argv[], Profile *pProfile, struct Synchronization *synch, SystemInformation *pSystem = nullptr);
|
||||
|
||||
private:
|
||||
bool _ReadParametersFromCmdLine(const int argc, const char *argv[], Profile *pProfile, struct Synchronization *synch, bool& fXMLProfile);
|
||||
bool _ReadParametersFromXmlFile(const char *pszPath, Profile *pProfile, vector<Target> *pvSubstTargets);
|
||||
|
||||
bool _ParseETWParameter(const char *arg, Profile *pProfile);
|
||||
bool _ParseFlushParameter(const char *arg, MemoryMappedIoFlushMode *FlushMode );
|
||||
bool _ParseAffinity(const char *arg, TimeSpan *pTimeSpan);
|
||||
bool _ParseRandomDistribution(const char *arg, vector<Target>& vTargets);
|
||||
|
||||
void _DisplayUsageInfo(const char *pszFilename) const;
|
||||
bool _GetSizeInBytes(const char *pszSize, UINT64& ullSize, const char **pszRest) const;
|
||||
bool _GetRandomDataWriteBufferData(const string& sArg, UINT64& cb, string& sPath);
|
||||
|
||||
static bool _IsSwitchChar(const char c) { return (c == '/' || c == '-'); }
|
||||
enum class ParseState {
|
||||
Unknown,
|
||||
True,
|
||||
False,
|
||||
Bad
|
||||
};
|
||||
|
||||
DWORD _dwBlockSize; // block size; other parameters may be stated in blocks
|
||||
// so the block size is needed to process them
|
||||
|
||||
UINT32 _ulWriteRatio; // default percentage of write requests
|
||||
|
||||
HANDLE _hEventStarted; // event signalled to notify that the actual (measured) test is to be started
|
||||
HANDLE _hEventFinished; // event signalled to notify that the actual test has finished
|
||||
|
||||
friend class UnitTests::CmdLineParserUnitTests;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
// Plain min/max macros from common headers will interfere with std::numeric_limits
|
||||
|
||||
#pragma push_macro("min")
|
||||
#pragma push_macro("max")
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
template<typename T>
|
||||
class Histogram
|
||||
{
|
||||
private:
|
||||
|
||||
mutable std::unordered_map<T, unsigned> _data;
|
||||
mutable unsigned _samples;
|
||||
|
||||
mutable std::map<T, unsigned> _sdata;
|
||||
mutable unsigned _ssamples;
|
||||
|
||||
// Save most recent percentile/iterator/nth-distance query. If the next is strictly >= it allows
|
||||
// an efficient forward iteration through an ascending set of queries.
|
||||
|
||||
mutable double _lastptile;
|
||||
mutable unsigned _lastptilen;
|
||||
mutable decltype(_sdata.cbegin()) _lastptilepos;
|
||||
|
||||
// A histogram starts writable/unsealed and automatically seals after the first read operation.
|
||||
// Subsequent writes which add data restart from empty.
|
||||
|
||||
void _SealData() const
|
||||
{
|
||||
if (!_data.empty())
|
||||
{
|
||||
_sdata.clear();
|
||||
|
||||
_sdata = std::map<T, unsigned>(_data.cbegin(), _data.cend());
|
||||
_ssamples = _samples;
|
||||
|
||||
// invalid ptile > 1; first ptile query will initialize
|
||||
_lastptile = 1.1;
|
||||
|
||||
_data.clear();
|
||||
_samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Histogram()
|
||||
: _samples(0),
|
||||
_ssamples(0)
|
||||
{}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
_data.clear();
|
||||
_samples = 0;
|
||||
|
||||
_sdata.clear();
|
||||
_ssamples = 0;
|
||||
|
||||
}
|
||||
|
||||
void Add(T v)
|
||||
{
|
||||
_data[v]++;
|
||||
_samples++;
|
||||
}
|
||||
|
||||
void Merge(const Histogram<T> &other)
|
||||
{
|
||||
for (auto i : other._data)
|
||||
{
|
||||
_data[ i.first ] += i.second;
|
||||
}
|
||||
|
||||
_samples += other._samples;
|
||||
}
|
||||
|
||||
T GetMin() const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
// Default low if empty
|
||||
if (!_ssamples)
|
||||
{
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
return _sdata.cbegin()->first;
|
||||
}
|
||||
|
||||
T GetMax() const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
// Default low if empty
|
||||
if (!_ssamples)
|
||||
{
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
return _sdata.crbegin()->first;
|
||||
}
|
||||
|
||||
unsigned GetSampleBuckets() const
|
||||
{
|
||||
return (unsigned) (_samples ? _data.size() : _sdata.size());
|
||||
}
|
||||
|
||||
unsigned GetSampleSize() const
|
||||
{
|
||||
return _samples ? _samples : _ssamples;
|
||||
}
|
||||
|
||||
T GetPercentile(double p) const
|
||||
{
|
||||
if ((p < 0.0) || (p > 1.0))
|
||||
{
|
||||
throw std::invalid_argument("Percentile must be >= 0 and <= 1");
|
||||
}
|
||||
|
||||
_SealData();
|
||||
|
||||
// Default low if empty
|
||||
if (!_ssamples)
|
||||
{
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
const double target = p * _ssamples;
|
||||
|
||||
// Default to beginning; n is the number of samples iterated over so far
|
||||
unsigned n = 0;
|
||||
auto pos = _sdata.cbegin();
|
||||
|
||||
// Resume from last?
|
||||
if (p >= _lastptile)
|
||||
{
|
||||
n = _lastptilen;
|
||||
pos = _lastptilepos;
|
||||
}
|
||||
|
||||
while (pos != _sdata.cend())
|
||||
{
|
||||
if (n + pos->second >= target)
|
||||
{
|
||||
// Save position. Note the pre-incremented distance through the histogram
|
||||
// must be saved in case next is still in the same bucket.
|
||||
_lastptile = p;
|
||||
_lastptilen = n;
|
||||
_lastptilepos = pos;
|
||||
|
||||
return pos->first;
|
||||
}
|
||||
|
||||
n += pos->second;
|
||||
++pos;
|
||||
}
|
||||
|
||||
throw std::overflow_error("overran end trying to find percentile");
|
||||
}
|
||||
|
||||
T GetPercentile(int p) const
|
||||
{
|
||||
return GetPercentile(static_cast<double>(p) / 100);
|
||||
}
|
||||
|
||||
T GetMedian() const
|
||||
{
|
||||
return GetPercentile(0.5);
|
||||
}
|
||||
|
||||
double GetStdDev() const { return GetStandardDeviation(); }
|
||||
double GetAvg() const { return GetMean(); }
|
||||
|
||||
double GetMean() const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
// Default low if empty
|
||||
if (!_ssamples)
|
||||
{
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
double sum(0);
|
||||
|
||||
for (const auto i : _sdata)
|
||||
{
|
||||
double bucket_val =
|
||||
static_cast<double>(i.first) * i.second / _ssamples;
|
||||
|
||||
if (sum + bucket_val < 0)
|
||||
{
|
||||
throw std::overflow_error("while trying to accumulate sum");
|
||||
}
|
||||
|
||||
sum += bucket_val;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
double GetStandardDeviation() const
|
||||
{
|
||||
double mean(GetMean());
|
||||
double ssd(0);
|
||||
|
||||
for (const auto i : _sdata)
|
||||
{
|
||||
double dev = static_cast<double>(i.first) - mean;
|
||||
double sqdev = dev * dev;
|
||||
ssd += i.second * sqdev;
|
||||
}
|
||||
|
||||
return sqrt(ssd / _ssamples);
|
||||
}
|
||||
|
||||
std::string GetHistogramCsv(const unsigned bins) const
|
||||
{
|
||||
return GetHistogramCsv(bins, GetMin(), GetMax());
|
||||
}
|
||||
|
||||
std::string GetHistogramCsv(const unsigned bins, const T LOW, const T HIGH) const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
// ISSUE-REVIEW
|
||||
// Currently bins are defined as strictly less-than
|
||||
// their upper limit, with the exception of the last
|
||||
// bin. Otherwise where would I put the max value?
|
||||
const double binSize = static_cast<double>((HIGH - LOW) / bins);
|
||||
double limit = static_cast<double>(LOW);
|
||||
|
||||
std::ostringstream os;
|
||||
os.precision(std::numeric_limits<T>::digits10);
|
||||
|
||||
auto pos = _sdata.cbegin();
|
||||
unsigned cumulative = 0;
|
||||
|
||||
for (unsigned bin = 1; bin <= bins; ++bin)
|
||||
{
|
||||
unsigned count = 0;
|
||||
limit += binSize;
|
||||
|
||||
while (pos != _sdata.end() &&
|
||||
(pos->first < limit || bin == bins))
|
||||
{
|
||||
count += pos->second;
|
||||
++pos;
|
||||
}
|
||||
|
||||
cumulative += count;
|
||||
|
||||
os << limit << "," << count << "," << cumulative << std::endl;
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string GetRawCsv() const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
std::ostringstream os;
|
||||
os.precision(std::numeric_limits<T>::digits10);
|
||||
|
||||
for (const auto i : _sdata)
|
||||
{
|
||||
os << i.first << "," << i.second << std::endl;
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string GetRaw() const
|
||||
{
|
||||
_SealData();
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
for (const auto i : _sdata)
|
||||
{
|
||||
os << i.second << " " << i.first << std::endl;
|
||||
}
|
||||
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pop_macro("min")
|
||||
#pragma pop_macro("max")
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#define INITGUID //Include this #define to use SystemTraceControlGuid in Evntrace.h.
|
||||
#include <Evntrace.h> //ETW
|
||||
#include <Winternl.h> //ntdll.dll
|
||||
|
||||
|
||||
void PrintError(const char *format, ...);
|
||||
namespace UnitTests
|
||||
{
|
||||
class IORequestGeneratorUnitTests;
|
||||
}
|
||||
|
||||
class IORequestGenerator
|
||||
{
|
||||
public:
|
||||
IORequestGenerator() :
|
||||
_hNTDLL(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//bool GenerateRequests(Profile& profile, IResultParser& resultParser, struct Synchronization *pSynch);
|
||||
/// for CrystalDiskMark
|
||||
bool GenerateRequests(Profile& profile, IResultParser& resultParser, struct Synchronization* pSynch, int* totalScore, double* averageLatency);
|
||||
|
||||
private:
|
||||
|
||||
struct CreateFileParameters
|
||||
{
|
||||
string sPath;
|
||||
UINT64 ullFileSize;
|
||||
bool fZeroWriteBuffers;
|
||||
};
|
||||
|
||||
bool _GenerateRequestsForTimeSpan(const Profile& profile, const TimeSpan& timeSpan, Results& results, struct Synchronization *pSynch);
|
||||
void _AbortWorkerThreads(HANDLE hStartEvent, vector<HANDLE>& vhThreads) const;
|
||||
void _CloseOpenFiles(vector<HANDLE>& vhFiles) const;
|
||||
DWORD _CreateDirectoryPath(const char *path) const;
|
||||
bool _CreateFile(UINT64 ullFileSize, const char *pszFilename, bool fZeroBuffers, bool fVerbose) const;
|
||||
bool _GetActiveGroupsAndProcs() const;
|
||||
struct ETWSessionInfo _GetResultETWSession(const EVENT_TRACE_PROPERTIES *pTraceProperties) const;
|
||||
bool _GetSystemPerfInfo(vector<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION>& vSPPI, bool fVerbose) const;
|
||||
void _InitializeGlobalParameters();
|
||||
bool _LoadDLLs();
|
||||
bool _StopETW(bool fUseETW, TRACEHANDLE hTraceSession) const;
|
||||
void _TerminateWorkerThreads(vector<HANDLE>& vhThreads) const;
|
||||
bool _ValidateProfile(const Profile& profile) const;
|
||||
vector<struct CreateFileParameters> _GetFilesToPrecreate(const Profile& profile) const;
|
||||
void _MarkFilesAsCreated(Profile& profile, const vector<struct CreateFileParameters>& vFiles) const;
|
||||
bool _PrecreateFiles(Profile& profile) const;
|
||||
|
||||
HINSTANCE volatile _hNTDLL; //handle to ntdll.dll
|
||||
|
||||
friend class UnitTests::IORequestGeneratorUnitTests;
|
||||
};
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include "IoBucketizer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
/*
|
||||
Calculating stddev using an online algorithm:
|
||||
avg = sum(1..n, a[n]) / n
|
||||
stddev = sqrt(sum(1..n, (a[n] - avg)^2) / n)
|
||||
= sqrt(sum(1..n, a[n]^2 - 2 * a[n] * avg + avg^2) / n)
|
||||
= sqrt((sum(1..n, a[n]^2) - 2 * avg * sum(1..n, a[n]) + n * avg^2) / n)
|
||||
= sqrt((sum(1..n, a[n]^2) - 2 * (sum(1..n, a[n]) / n) * sum(1..n, a[n]) + n * (sum(1..n], a[n]) / n)^2) / n)
|
||||
= sqrt((sum(1..n, a[n]^2) - (2 / n) * sum(1..n, a[n])^2 + (1 / n) * sum(1..n, a[n])^2) / n)
|
||||
= sqrt((sum(1..n, a[n]^2) - (1 / n) * sum(1..n, a[n])^2) / n)
|
||||
|
||||
So if we track n, sum(a[n]) and sum(a[n]^2) we can calculate the stddev. This
|
||||
is used to calculate the stddev of the latencies below.
|
||||
*/
|
||||
|
||||
const unsigned __int64 INVALID_BUCKET_DURATION = 0;
|
||||
|
||||
IoBucketizer::IoBucketizer()
|
||||
: _bucketDuration(INVALID_BUCKET_DURATION),
|
||||
_validBuckets(0),
|
||||
_totalBuckets(0)
|
||||
{}
|
||||
|
||||
void IoBucketizer::Initialize(unsigned __int64 bucketDuration, size_t validBuckets)
|
||||
{
|
||||
if (_bucketDuration != INVALID_BUCKET_DURATION)
|
||||
{
|
||||
throw std::runtime_error("IoBucketizer has already been initialized");
|
||||
}
|
||||
if (bucketDuration == INVALID_BUCKET_DURATION)
|
||||
{
|
||||
throw std::invalid_argument("Bucket duration must be a positive integer");
|
||||
}
|
||||
|
||||
_bucketDuration = bucketDuration;
|
||||
_validBuckets = validBuckets;
|
||||
_vBuckets.resize(_validBuckets);
|
||||
}
|
||||
|
||||
void IoBucketizer::Add(unsigned __int64 ioCompletionTime, double ioDuration)
|
||||
{
|
||||
if (_bucketDuration == INVALID_BUCKET_DURATION)
|
||||
{
|
||||
throw std::runtime_error("IoBucketizer has not been initialized");
|
||||
}
|
||||
|
||||
size_t bucketNumber = static_cast<size_t>(ioCompletionTime / _bucketDuration);
|
||||
_totalBuckets = bucketNumber + 1;
|
||||
|
||||
if (bucketNumber >= _validBuckets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_vBuckets[bucketNumber].lfSumDuration += ioDuration;
|
||||
_vBuckets[bucketNumber].lfSumSqrDuration += ioDuration * ioDuration;
|
||||
|
||||
if (_vBuckets[bucketNumber].ulCount == 0 ||
|
||||
ioDuration < _vBuckets[bucketNumber].lfMinDuration)
|
||||
{
|
||||
_vBuckets[bucketNumber].lfMinDuration = ioDuration;
|
||||
}
|
||||
if (_vBuckets[bucketNumber].ulCount == 0 ||
|
||||
ioDuration > _vBuckets[bucketNumber].lfMaxDuration)
|
||||
{
|
||||
_vBuckets[bucketNumber].lfMaxDuration = ioDuration;
|
||||
}
|
||||
|
||||
_vBuckets[bucketNumber].ulCount++;
|
||||
}
|
||||
|
||||
size_t IoBucketizer::GetNumberOfValidBuckets() const
|
||||
{
|
||||
return (_totalBuckets > _validBuckets ? _validBuckets : _totalBuckets);
|
||||
}
|
||||
|
||||
unsigned int IoBucketizer::GetIoBucketCount(size_t bucketNumber) const
|
||||
{
|
||||
if (bucketNumber < _validBuckets)
|
||||
{
|
||||
return _vBuckets[bucketNumber].ulCount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double IoBucketizer::GetIoBucketMinDurationUsec(size_t bucketNumber) const
|
||||
{
|
||||
if (bucketNumber < _validBuckets)
|
||||
{
|
||||
return _vBuckets[bucketNumber].lfMinDuration;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double IoBucketizer::GetIoBucketMaxDurationUsec(size_t bucketNumber) const
|
||||
{
|
||||
if (bucketNumber < _validBuckets)
|
||||
{
|
||||
return _vBuckets[bucketNumber].lfMaxDuration;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double IoBucketizer::GetIoBucketAvgDurationUsec(size_t bucketNumber) const
|
||||
{
|
||||
if (bucketNumber < _validBuckets && _vBuckets[bucketNumber].ulCount != 0)
|
||||
{
|
||||
return _vBuckets[bucketNumber].lfSumDuration / static_cast<double>(_vBuckets[bucketNumber].ulCount);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double IoBucketizer::GetIoBucketDurationStdDevUsec(size_t bucketNumber) const
|
||||
{
|
||||
if (bucketNumber < _validBuckets && _vBuckets[bucketNumber].ulCount != 0)
|
||||
{
|
||||
double sum_of_squares = _vBuckets[bucketNumber].lfSumSqrDuration;
|
||||
double square_of_sum = _vBuckets[bucketNumber].lfSumDuration * _vBuckets[bucketNumber].lfSumDuration;
|
||||
double count = static_cast<double>(_vBuckets[bucketNumber].ulCount);
|
||||
double square_stddev = (sum_of_squares - (square_of_sum / count)) / count;
|
||||
|
||||
return sqrt(square_stddev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double IoBucketizer::_GetMeanIOPS() const
|
||||
{
|
||||
size_t numBuckets = GetNumberOfValidBuckets();
|
||||
double sum = 0;
|
||||
|
||||
for (size_t i = 0; i < numBuckets; i++)
|
||||
{
|
||||
sum += static_cast<double>(_vBuckets[i].ulCount) / numBuckets;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
double IoBucketizer::GetStandardDeviationIOPS() const
|
||||
{
|
||||
size_t numBuckets = GetNumberOfValidBuckets();
|
||||
|
||||
if(numBuckets == 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double mean = _GetMeanIOPS();
|
||||
double ssd = 0;
|
||||
|
||||
for (size_t i = 0; i < numBuckets; i++)
|
||||
{
|
||||
double dev = static_cast<double>(_vBuckets[i].ulCount) - mean;
|
||||
double sqdev = dev*dev;
|
||||
ssd += sqdev;
|
||||
}
|
||||
|
||||
return sqrt(ssd / numBuckets);
|
||||
}
|
||||
|
||||
void IoBucketizer::Merge(const IoBucketizer& other)
|
||||
{
|
||||
if(other._vBuckets.size() > _vBuckets.size())
|
||||
{
|
||||
_vBuckets.resize(other._vBuckets.size());
|
||||
}
|
||||
for(size_t i = 0; i < other._vBuckets.size(); i++)
|
||||
{
|
||||
_vBuckets[i].ulCount += other._vBuckets[i].ulCount;
|
||||
_vBuckets[i].lfSumDuration += other._vBuckets[i].lfSumDuration;
|
||||
_vBuckets[i].lfSumSqrDuration += other._vBuckets[i].lfSumSqrDuration;
|
||||
|
||||
if (i >= _validBuckets ||
|
||||
other._vBuckets[i].lfMinDuration < _vBuckets[i].lfMinDuration)
|
||||
{
|
||||
_vBuckets[i].lfMinDuration = other._vBuckets[i].lfMinDuration;
|
||||
}
|
||||
if (other._vBuckets[i].lfMaxDuration > _vBuckets[i].lfMaxDuration)
|
||||
{
|
||||
_vBuckets[i].lfMaxDuration = other._vBuckets[i].lfMaxDuration;
|
||||
}
|
||||
}
|
||||
if (other._validBuckets > _validBuckets)
|
||||
{
|
||||
_validBuckets = other._validBuckets;
|
||||
}
|
||||
if (other._totalBuckets > _totalBuckets)
|
||||
{
|
||||
_totalBuckets = other._totalBuckets;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
class IoBucketizer
|
||||
{
|
||||
public:
|
||||
IoBucketizer();
|
||||
void Initialize(unsigned __int64 bucketDuration, size_t validBuckets);
|
||||
|
||||
size_t GetNumberOfValidBuckets() const;
|
||||
unsigned int GetIoBucketCount(size_t bucketNumber) const;
|
||||
double GetIoBucketMinDurationUsec(size_t bucketNumber) const;
|
||||
double GetIoBucketMaxDurationUsec(size_t bucketNumber) const;
|
||||
double GetIoBucketAvgDurationUsec(size_t bucketNumber) const;
|
||||
double GetIoBucketDurationStdDevUsec(size_t bucketNumber) const;
|
||||
void Add(unsigned __int64 ioCompletionTime, double ioDuration);
|
||||
double GetStandardDeviationIOPS() const;
|
||||
void Merge(const IoBucketizer& other);
|
||||
private:
|
||||
double _GetMeanIOPS() const;
|
||||
|
||||
struct IoBucket {
|
||||
IoBucket() :
|
||||
ulCount(0),
|
||||
lfMinDuration(0),
|
||||
lfMaxDuration(0),
|
||||
lfSumDuration(0),
|
||||
lfSumSqrDuration(0)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int ulCount;
|
||||
double lfMinDuration;
|
||||
double lfMaxDuration;
|
||||
double lfSumDuration;
|
||||
double lfSumSqrDuration;
|
||||
};
|
||||
|
||||
unsigned __int64 _bucketDuration;
|
||||
size_t _validBuckets;
|
||||
size_t _totalBuckets;
|
||||
std::vector<IoBucket> _vBuckets;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
//
|
||||
// OverlappedQueue is a simple class that implements a queue for OVERLAPPED elements
|
||||
//
|
||||
class OverlappedQueue
|
||||
{
|
||||
public:
|
||||
OverlappedQueue(void);
|
||||
|
||||
void Add(OVERLAPPED *pOverlapped);
|
||||
bool IsEmpty(void) const;
|
||||
OVERLAPPED * Remove(void);
|
||||
size_t GetCount() const;
|
||||
|
||||
private:
|
||||
OVERLAPPED *_pHead;
|
||||
OVERLAPPED *_pTail;
|
||||
size_t _cItems;
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
class ResultParserUnitTests;
|
||||
}
|
||||
|
||||
class ResultParser : public IResultParser
|
||||
{
|
||||
public:
|
||||
string ParseResults(const Profile& profile, const SystemInformation& system, vector<Results> vResults);
|
||||
string ParseProfile(const Profile& profile);
|
||||
|
||||
/// for CrystalDiskMark
|
||||
int GetTotalScore();
|
||||
double GetAverageLatency();
|
||||
|
||||
private:
|
||||
void _DisplayFileSize(UINT64 fsize, UINT32 align = 0);
|
||||
void _DisplayETWSessionInfo(struct ETWSessionInfo sessionInfo);
|
||||
void _DisplayETW(struct ETWMask ETWMask, struct ETWEventCounters EtwEventCounters);
|
||||
void _Print(const char *format, ...);
|
||||
void _PrintProfile(const Profile& profile);
|
||||
void _PrintSystemInfo(const SystemInformation& system);
|
||||
void _PrintCpuUtilization(const Results& results, const SystemInformation& system);
|
||||
enum class _SectionEnum {TOTAL, READ, WRITE};
|
||||
void _PrintSectionFieldNames(const TimeSpan& timeSpan);
|
||||
void _PrintSectionBorderLine(const TimeSpan& timeSpan);
|
||||
void _PrintSection(_SectionEnum, const TimeSpan&, const Results&);
|
||||
void _PrintLatencyPercentiles(const Results&);
|
||||
void _PrintLatencyChart(const Histogram<float>& readLatencyHistogram,
|
||||
const Histogram<float>& writeLatencyHistogram,
|
||||
const Histogram<float>& totalLatencyHistogram);
|
||||
void _PrintTimeSpan(const TimeSpan &timeSpan);
|
||||
void _PrintTarget(const Target &target, bool fUseThreadsPerFile, bool fUseRequestsPerFile, bool fCompletionRoutines);
|
||||
void _PrintDistribution(DistributionType dT, const vector<DistributionRange>& v, char* spc);
|
||||
void _PrintEffectiveDistributions(const Results& results);
|
||||
void _PrintWaitStats(const Results& result);
|
||||
|
||||
string _sResult;
|
||||
/// for CrystalDiskMark
|
||||
int _totalScore;
|
||||
double _averageLatency;
|
||||
|
||||
friend class UnitTests::ResultParserUnitTests;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
// ThroughputMeter class assists in metering out throughput over
|
||||
// time. The meter is started by calling Start() with the throughput
|
||||
// to be simulated. GetSleepTime() returns 0 when the next IO can be issued.
|
||||
// Adjust() is called to notify the ThroughputMeter about how many bytes were read/written.
|
||||
class ThroughputMeter
|
||||
{
|
||||
public:
|
||||
ThroughputMeter(void);
|
||||
|
||||
bool IsRunning(void) const;
|
||||
void Start(DWORD cBytesPerMillisecond, DWORD dwBlockSize, DWORD dwThinkTime, DWORD dwBurstSize);
|
||||
DWORD GetSleepTime(void) const;
|
||||
void Adjust(size_t cb);
|
||||
|
||||
private:
|
||||
DWORD _GetThrottleTime(void) const;
|
||||
|
||||
bool _fRunning; // true = throughput monitoring is on
|
||||
bool _fThrottle; // true = throttling is on
|
||||
bool _fThink; // true = think time is enabled
|
||||
ULONGLONG _cbCompleted; // completed IO
|
||||
DWORD _cbBlockSize;
|
||||
DWORD _cBytesPerMillisecond; // rate of throttling
|
||||
ULONGLONG _ullStartTimestamp;
|
||||
ULONGLONG _ullDelayUntil; // timestamp at which the next IO can be executed
|
||||
DWORD _thinkTime; // time to sleep between burst of IOs
|
||||
DWORD _burstSize; // number of IOs in a burst. meaningless if think time is zero
|
||||
DWORD _cIO; // count of IOs in the current burst
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// versioning material. for simplicity in consumption, please ensure that the date string
|
||||
// parses via the System.Datetime constructor as follows (in Powershell):
|
||||
//
|
||||
// [datetime] "string"
|
||||
//
|
||||
// this should result in a valid System.Datetime object, rendered like:
|
||||
//
|
||||
// Monday, June 16, 2014 12:00:00 AM
|
||||
|
||||
#define DISKSPD_RELEASE_TAG ""
|
||||
#define DISKSPD_REVISION ""
|
||||
|
||||
#define DISKSPD_MAJOR 2
|
||||
#define DISKSPD_MINOR 2
|
||||
#define DISKSPD_BUILD 0
|
||||
#define DISKSPD_QFE 0
|
||||
|
||||
#define DISKSPD_MAJORMINOR_VER_STR(x,y,z) #x "." #y "." #z
|
||||
#define DISKSPD_MAJORMINOR_VERSION_STRING(x,y,z) DISKSPD_MAJORMINOR_VER_STR(x,y,z)
|
||||
#define DISKSPD_MAJORMINOR_VERSION_STR DISKSPD_MAJORMINOR_VERSION_STRING(DISKSPD_MAJOR, DISKSPD_MINOR, DISKSPD_BUILD)
|
||||
|
||||
#define DISKSPD_NUMERIC_VERSION_STRING DISKSPD_MAJORMINOR_VERSION_STR DISKSPD_REVISION DISKSPD_RELEASE_TAG
|
||||
#define DISKSPD_DATE_VERSION_STRING "2024/6/3"
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <MsXml6.h>
|
||||
#include "Common.h"
|
||||
|
||||
class XmlProfileParser
|
||||
{
|
||||
public:
|
||||
bool ParseFile(const char *pszPath, Profile *pProfile, vector<Target> *pvSubstTargets, HMODULE hModule);
|
||||
|
||||
private:
|
||||
HRESULT _ParseEtw(IXMLDOMDocument2 *pXmlDoc, Profile *pProfile);
|
||||
HRESULT _ParseTimeSpans(IXMLDOMDocument2 *pXmlDoc, Profile *pProfile, vector<pair<string, bool>>& vSubsts);
|
||||
HRESULT _ParseTimeSpan(IXMLDOMNode *pXmlNode, TimeSpan *pTimeSpan, vector<pair<string, bool>>& vSubsts);
|
||||
HRESULT _ParseTargets(IXMLDOMNode *pXmlNode, TimeSpan *pTimeSpan, vector<pair<string, bool>>& vSubsts);
|
||||
HRESULT _ParseRandomDataSource(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _ParseWriteBufferContent(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _ParseTarget(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _ParseThreadTargets(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _ParseThroughput(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _ParseThreadTarget(IXMLDOMNode *pXmlNode, ThreadTarget *pThreadTarget);
|
||||
HRESULT _ParseAffinityAssignment(IXMLDOMNode *pXmlNode, TimeSpan *pTimeSpan);
|
||||
HRESULT _ParseAffinityGroupAssignment(IXMLDOMNode *pXmlNode, TimeSpan *pTimeSpan);
|
||||
HRESULT _ParseDistribution(IXMLDOMNode *pXmlNode, Target *pTarget);
|
||||
HRESULT _SubstTarget(Target *pTarget, vector<pair<string, bool>>& vSubsts);
|
||||
|
||||
HRESULT _GetString(IXMLDOMNode *pXmlNode, const char *pszQuery, string *psValue) const;
|
||||
HRESULT _GetUINT32(IXMLDOMNode *pXmlNode, const char *pszQuery, UINT32 *pulValue) const;
|
||||
HRESULT _GetUINT64(IXMLDOMNode *pXmlNode, const char *pszQuery, UINT64 *pullValue) const;
|
||||
HRESULT _GetDWORD(IXMLDOMNode *pXmlNode, const char *pszQuery, DWORD *pdwValue) const;
|
||||
HRESULT _GetBool(IXMLDOMNode *pXmlNode, const char *pszQuery, bool *pfValue) const;
|
||||
|
||||
HRESULT _GetUINT32Attr(IXMLDOMNode *pXmlNode, const char *pszAttr, UINT32 *pulValue) const;
|
||||
|
||||
HRESULT _GetVerbose(IXMLDOMDocument2 *pXmlDoc, bool *pfVerbose);
|
||||
HRESULT _GetProgress(IXMLDOMDocument2 *pXmlDoc, DWORD *pdwProgress);
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Common.h"
|
||||
|
||||
class XmlResultParser: public IResultParser
|
||||
{
|
||||
public:
|
||||
string ParseResults(const Profile& profile, const SystemInformation& system, vector<Results> vResults);
|
||||
string ParseProfile(const Profile& profile);
|
||||
/// for CrystalDiskMark
|
||||
int GetTotalScore();
|
||||
double GetAverageLatency();
|
||||
|
||||
private:
|
||||
void _PrintCpuUtilization(const Results& results, const SystemInformation& system);
|
||||
void _PrintETW(struct ETWMask ETWMask, struct ETWEventCounters EtwEventCounters);
|
||||
void _PrintETWSessionInfo(struct ETWSessionInfo sessionInfo);
|
||||
void _PrintLatencyPercentiles(const Results& results);
|
||||
void _PrintTargetResults(const TargetResults& results);
|
||||
void _PrintTargetLatency(const TargetResults& results);
|
||||
void _PrintTargetIops(const IoBucketizer& readBucketizer, const IoBucketizer& writeBucketizer, UINT32 bucketTimeInMs);
|
||||
void _PrintOverallIops(const Results& results, UINT32 bucketTimeInMs);
|
||||
void _PrintIops(const IoBucketizer& readBucketizer, const IoBucketizer& writeBucketizer, UINT32 bucketTimeInMs);
|
||||
void _PrintWaitStats(const ThreadResults& threadResult);
|
||||
|
||||
void _PrintV(const char *format, va_list listArg);
|
||||
void _Print(const char *format, ...);
|
||||
void _PrintInc(const char *format, ...);
|
||||
void _PrintDec(const char *format, ...);
|
||||
|
||||
string _sResult;
|
||||
UINT32 _indent = 0;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __DISKSPD_ERRORS_H
|
||||
#define __DISKSPD_ERRORS_H
|
||||
|
||||
#define ERROR_LOAD_LIBRARY 1 //error during LoadLibrary call
|
||||
#define ERROR_GET_PROC_ADDRESS 2 //error during GetProcAddress
|
||||
#define ERROR_PARSE_CMD_LINE 3 //error parsing cmd line parameters
|
||||
#define ERROR_WAIT_FOR_START_SIGNAL 4 //error waiting for a signal to start work
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
|
||||
DISKSPD
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <Wmistr.h> ///WNODE_HEADER
|
||||
#define INITGUID //Include this #define to use SystemTraceControlGuid in Evntrace.h.
|
||||
#include <Evntrace.h> //ETW
|
||||
#include "Common.h"
|
||||
|
||||
BOOL TraceEvents();
|
||||
TRACEHANDLE StartETWSession(const Profile& profile);
|
||||
PEVENT_TRACE_PROPERTIES StopETWSession(TRACEHANDLE hTraceSession);
|
||||
Reference in New Issue
Block a user