This contains my bachelors thesis and associated tex files, code snippets and maybe more. Topic: Data Movement in Heterogeneous Memories with Intel Data Streaming Accelerator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.6 KiB

  1. #include <iostream>
  2. #include <random>
  3. #include <vector>
  4. #include <string>
  5. #include <omp.h>
  6. #include "cache.hpp"
  7. dsacache::Cache CACHE;
  8. void InitCache(const std::string& device) {
  9. if (device == "default") {
  10. auto cache_policy = [](const int numa_dst_node, const int numa_src_node, const size_t data_size) {
  11. return numa_dst_node;
  12. };
  13. auto copy_policy = [](const int numa_dst_node, const int numa_src_node) {
  14. return std::vector<int>{ numa_src_node, numa_dst_node };
  15. };
  16. CACHE.Init(cache_policy,copy_policy);
  17. }
  18. else if (device == "xeonmax") {
  19. auto cache_policy = [](const int numa_dst_node, const int numa_src_node, const size_t data_size) {
  20. return numa_dst_node < 8 ? numa_dst_node + 8 : numa_dst_node;
  21. };
  22. auto copy_policy = [](const int numa_dst_node, const int numa_src_node) {
  23. const bool same_socket = ((numa_dst_node ^ numa_src_node) & 4) == 0;
  24. if (same_socket) {
  25. const bool socket_number = numa_dst_node >> 2;
  26. if (socket_number == 0) return std::vector<int>{ 0, 1, 2, 3 };
  27. else return std::vector<int>{ 4, 5, 6, 7 };
  28. }
  29. else return std::vector<int>{ numa_src_node, numa_dst_node };
  30. };
  31. CACHE.Init(cache_policy,copy_policy);
  32. }
  33. else {
  34. std::cerr << "Given device '" << device << "' not supported!" << std::endl;
  35. exit(-1);
  36. }
  37. }
  38. double* GetRandomArray(const size_t size) {
  39. double* array = new double[size];
  40. std::uniform_real_distribution<double> unif(std::numeric_limits<double>::min(), std::numeric_limits<double>::max());
  41. std::default_random_engine re;
  42. for (size_t i = 0; i < size; i++) {
  43. array[i] = unif(re);
  44. }
  45. return array;
  46. }
  47. bool IsEqual(const double* a, const double* b, const size_t size) {
  48. for (size_t i = 0; i < size; i++) {
  49. try {
  50. if (a[i] != b[i]) return false;
  51. }
  52. catch (...) {
  53. return false;
  54. }
  55. }
  56. return true;
  57. }
  58. void PerformAccessAndTest(double* src, const size_t size, const int tid) {
  59. std::unique_ptr<dsacache::CacheData> data_cache = CACHE.Access(
  60. reinterpret_cast<uint8_t *>(src),
  61. size * sizeof(double)
  62. );
  63. double* cached_imm = reinterpret_cast<double *>(data_cache->GetDataLocation());
  64. // check the value immediately just to see if ram or cache was returned
  65. if (src == cached_imm) {
  66. std::cout << "[" << tid << "] Caching did not immediately yield different data location." << std::endl;
  67. }
  68. else if (cached_imm == nullptr) {
  69. std::cout << "[" << tid << "] Immediately got nullptr." << std::endl;
  70. }
  71. else {
  72. std::cout << "[" << tid << "] Immediately got different data location." << std::endl;
  73. }
  74. // waits for the completion of the asynchronous caching operation
  75. data_cache->WaitOnCompletion();
  76. // gets the cache-data-location from the struct
  77. double* cached = reinterpret_cast<double *>(data_cache->GetDataLocation());
  78. // tests on the resulting value
  79. if (src == cached) {
  80. std::cout << "[" << tid << "] Caching did not affect data location." << std::endl;
  81. }
  82. else if (cached == nullptr) {
  83. std::cerr << "[" << tid << "] Got nullptr from cache." << std::endl;
  84. }
  85. else {
  86. std::cout << "[" << tid << "] Got different data location from cache." << std::endl;
  87. }
  88. if (IsEqual(src,cached,size)) {
  89. std::cout << "[" << tid << "] Cached data is correct." << std::endl;
  90. }
  91. else {
  92. std::cerr << "[" << tid << "] Cached data is wrong." << std::endl;
  93. }
  94. }
  95. void RunTestST(const size_t size) {
  96. double* data = GetRandomArray(size);
  97. static constexpr int tid = 0;
  98. std::cout << "[" << tid << "] first access --- " << std::endl;
  99. PerformAccessAndTest(data, size, tid);
  100. std::cout << "[" << tid << "] second access --- " << std::endl;
  101. PerformAccessAndTest(data, size, tid);
  102. std::cout << "[" << tid << "] end of application --- " << std::endl;
  103. }
  104. void RunTestMT(const size_t size) {
  105. double* data = GetRandomArray(size);
  106. #pragma omp parallel
  107. {
  108. const int tid = omp_get_thread_num();
  109. std::cout << "[" << tid << "] first access --- " << std::endl;
  110. PerformAccessAndTest(data, size, tid);
  111. std::cout << "[" << tid << "] second access --- " << std::endl;
  112. PerformAccessAndTest(data, size, tid);
  113. std::cout << "[" << tid << "] end of block --- " << std::endl;
  114. }
  115. }
  116. int main(int argc, char **argv) {
  117. if (argc != 4) {
  118. std::cerr << "This application requires four parameters!" << std::endl;
  119. std::cout << "Please provide the following positional arguments: [device] [mode] [size]" << std::endl;
  120. std::cout << "[device] from { default, xeonmax } which influences cache and execution placement" << std::endl;
  121. std::cout << "[mode] from { st, mt } or single and multi threaded respectively" << std::endl;
  122. std::cout << "[size] positive integral number, amount of float64 in data array" << std::endl;
  123. exit(-1);
  124. }
  125. const std::string device = argv[1];
  126. const std::string mode = argv[2];
  127. const std::string size_s = argv[3];
  128. uint32_t size = 0;
  129. try {
  130. size = std::stoul(size_s);
  131. }
  132. catch (...) {
  133. std::cerr << "Given Size '" << size_s << "' caused error during conversion to number!" << std::endl;
  134. }
  135. InitCache(device);
  136. if (mode == "st") {
  137. RunTestST(size);
  138. }
  139. else if (mode == "mt") {
  140. RunTestMT(size);
  141. }
  142. else {
  143. std::cerr << "Given Mode '" << mode << "' not supported!" << std::endl;
  144. exit(-1);
  145. }
  146. }