|
|
@ -44,10 +44,10 @@ void InitCache(const std::string& device) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
double* GetRandomArray(const size_t size) { |
|
|
|
double* array = new double[size]; |
|
|
|
uint8_t* GetRandomArray(const size_t size) { |
|
|
|
uint8_t* array = new uint8_t[size]; |
|
|
|
|
|
|
|
std::uniform_real_distribution<double> unif(std::numeric_limits<double>::min(), std::numeric_limits<double>::max()); |
|
|
|
std::uniform_int_distribution<uint8_t> unif(std::numeric_limits<uint8_t>::min(), std::numeric_limits<uint8_t>::max()); |
|
|
|
std::default_random_engine re; |
|
|
|
|
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
@ -57,7 +57,7 @@ double* GetRandomArray(const size_t size) { |
|
|
|
return array; |
|
|
|
} |
|
|
|
|
|
|
|
bool IsEqual(const double* a, const double* b, const size_t size) { |
|
|
|
bool IsEqual(const uint8_t* a, const uint8_t* b, const size_t size) { |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
try { |
|
|
|
if (a[i] != b[i]) return false; |
|
|
@ -70,13 +70,13 @@ bool IsEqual(const double* a, const double* b, const size_t size) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void PerformAccessAndTest(double* src, const size_t size, const int tid) { |
|
|
|
std::unique_ptr<dsacache::CacheData> PerformAccessAndTest(uint8_t* src, const size_t size, const int tid) { |
|
|
|
std::unique_ptr<dsacache::CacheData> data_cache = CACHE.Access( |
|
|
|
reinterpret_cast<uint8_t *>(src), |
|
|
|
size * sizeof(double) |
|
|
|
size * sizeof(uint8_t) |
|
|
|
); |
|
|
|
|
|
|
|
double* cached_imm = reinterpret_cast<double *>(data_cache->GetDataLocation()); |
|
|
|
uint8_t* cached_imm = reinterpret_cast<uint8_t *>(data_cache->GetDataLocation()); |
|
|
|
|
|
|
|
// check the value immediately just to see if ram or cache was returned
|
|
|
|
|
|
|
@ -96,7 +96,7 @@ void PerformAccessAndTest(double* src, const size_t size, const int tid) { |
|
|
|
|
|
|
|
// gets the cache-data-location from the struct
|
|
|
|
|
|
|
|
double* cached = reinterpret_cast<double *>(data_cache->GetDataLocation()); |
|
|
|
uint8_t* cached = reinterpret_cast<uint8_t *>(data_cache->GetDataLocation()); |
|
|
|
|
|
|
|
// tests on the resulting value
|
|
|
|
|
|
|
@ -116,10 +116,12 @@ void PerformAccessAndTest(double* src, const size_t size, const int tid) { |
|
|
|
else { |
|
|
|
std::cerr << "[" << tid << "] Cached data is wrong." << std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
return std::move(data_cache); |
|
|
|
} |
|
|
|
|
|
|
|
void RunTestST(const size_t size) { |
|
|
|
double* data = GetRandomArray(size); |
|
|
|
uint8_t* data = GetRandomArray(size); |
|
|
|
|
|
|
|
static constexpr int tid = 0; |
|
|
|
|
|
|
@ -135,7 +137,7 @@ void RunTestST(const size_t size) { |
|
|
|
} |
|
|
|
|
|
|
|
void RunTestMT(const size_t size) { |
|
|
|
double* data = GetRandomArray(size); |
|
|
|
uint8_t* data = GetRandomArray(size); |
|
|
|
|
|
|
|
#pragma omp parallel
|
|
|
|
{ |
|
|
@ -153,14 +155,44 @@ void RunTestMT(const size_t size) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void RunTestFlush(const size_t size) { |
|
|
|
uint8_t* data1 = GetRandomArray(size); |
|
|
|
uint8_t* data2 = GetRandomArray(size); |
|
|
|
uint8_t* data3 = GetRandomArray(size); |
|
|
|
|
|
|
|
static constexpr int tid = 0; |
|
|
|
|
|
|
|
std::cout << "[" << tid << "] first access to data d1 and keepalive --- " << std::endl; |
|
|
|
|
|
|
|
const auto c1 = PerformAccessAndTest(data1, size, tid); |
|
|
|
|
|
|
|
std::cout << "[" << tid << "] second access to d2 lets d2 vanish --- " << std::endl; |
|
|
|
|
|
|
|
PerformAccessAndTest(data2, size, tid); |
|
|
|
|
|
|
|
std::cout << "[" << tid << "] third access to d3 should clear d2 --- " << std::endl; |
|
|
|
|
|
|
|
PerformAccessAndTest(data3, size, tid); |
|
|
|
|
|
|
|
std::cout << "[" << tid << "] end of block and test d1 == cache1 --- " << std::endl; |
|
|
|
|
|
|
|
if (IsEqual(data1, c1->GetDataLocation(), size)) { |
|
|
|
std::cout << "[" << tid << "] Cached d1 is still correct." << std::endl; |
|
|
|
} |
|
|
|
else { |
|
|
|
std::cerr << "[" << tid << "] Cached d1 is bad." << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int main(int argc, char **argv) { |
|
|
|
if (argc != 4) { |
|
|
|
std::cerr << "This application requires four parameters!" << std::endl; |
|
|
|
std::cerr << "This application requires three parameters!" << std::endl; |
|
|
|
|
|
|
|
std::cout << "Please provide the following positional arguments: [device] [mode] [size]" << std::endl; |
|
|
|
std::cout << "[device] from { default, xeonmax } which influences cache and execution placement" << std::endl; |
|
|
|
std::cout << "[mode] from { st, mt } or single and multi threaded respectively" << std::endl; |
|
|
|
std::cout << "[size] positive integral number, amount of float64 in data array" << std::endl; |
|
|
|
std::cout << "[mode] from { st, mt, flt } or single and multi threaded and flushtest respectively" << std::endl; |
|
|
|
std::cout << "[size] positive integral number, amount of bytes in data array" << std::endl; |
|
|
|
std::cout << "for flushtest the given size should be 1/3 of the available cache size" << std::endl; |
|
|
|
|
|
|
|
exit(-1); |
|
|
|
} |
|
|
@ -186,6 +218,9 @@ int main(int argc, char **argv) { |
|
|
|
else if (mode == "mt") { |
|
|
|
RunTestMT(size); |
|
|
|
} |
|
|
|
else if (mode == "flt") { |
|
|
|
RunTestFlush(size); |
|
|
|
} |
|
|
|
else { |
|
|
|
std::cerr << "Given Mode '" << mode << "' not supported!" << std::endl; |
|
|
|
exit(-1); |
|
|
|