#include #include #include "cache.hpp" dsacache::Cache CACHE; double* GetRandomArray(const size_t size) { double* array = new double[size]; std::uniform_real_distribution unif(std::numeric_limits::min(), std::numeric_limits::max()); std::default_random_engine re; for (size_t i = 0; i < size; i++) { array[i] = unif(re); } return array; } bool IsEqual(const double* a, const double* b, const size_t size) { for (size_t i = 0; i < size; i++) { try { if (a[i] != b[i]) return false; } catch (...) { return false; } } return true; } void PerformAccessAndTest(double* src, const size_t size) { std::unique_ptr data_cache = CACHE.Access( reinterpret_cast(src), size * sizeof(double) ); double* cached_imm = reinterpret_cast(data_cache->GetDataLocation()); // check the value immediately just to see if ram or cache was returned if (src == cached_imm) { std::cout << "Caching did not immediately yield different data location." << std::endl; } else if (cached_imm == nullptr) { std::cout << "Immediately got nullptr." << std::endl; } else { std::cout << "Immediately got different data location." << std::endl; } // waits for the completion of the asynchronous caching operation data_cache->WaitOnCompletion(); // gets the cache-data-location from the struct double* cached = reinterpret_cast(data_cache->GetDataLocation()); // tests on the resulting value if (src == cached) { std::cout << "Caching did not affect data location." << std::endl; } else if (cached == nullptr) { std::cout << "Got nullptr from cache." << std::endl; } else { std::cout << "Got different data location from cache." << std::endl; } if (IsEqual(src,cached,size)) { std::cout << "Cached data is correct." << std::endl; } else { std::cout << "Cached data is wrong." << std::endl; } } int main(int argc, char **argv) { // given numa destination and source node and the size of the data // this function decides on which the data will be placed // which is used to select the HBM-node for the dst-node if desired auto cache_policy = [](const int numa_dst_node, const int numa_src_node, const size_t data_size) { return numa_dst_node; }; // this function receives the memory source and destination node // and then decides, on which nodes the copy operation will be split auto copy_policy = [](const int numa_dst_node, const int numa_src_node) { return std::vector{ numa_src_node, numa_dst_node }; }; // initializes the cache with the two policies CACHE.Init(cache_policy,copy_policy); // generate the test data static constexpr size_t data_size = 1024 * 1024; double* data = GetRandomArray(data_size); std::cout << "--- first access --- " << std::endl; PerformAccessAndTest(data, data_size); std::cout << "--- second access --- " << std::endl; PerformAccessAndTest(data, data_size); std::cout << "--- end of application --- " << std::endl; }