mandelbench.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <chrono>
  4. #include <functional>
  5. #include <Mandel.h>
  6. #include <cmath>
  7. #include "Fixed.h"
  8. constexpr mnd::MandelViewport benchViewport(void)
  9. {
  10. return mnd::MandelViewport{ -1.250000598933854152929, 0.0001879894057291665530, 0.0000003839916666666565, 0.0000003839916666666565 };
  11. }
  12. const std::vector<mnd::MandelInfo> benches {
  13. mnd::MandelInfo{ benchViewport(), 100, 100, 1000 },
  14. mnd::MandelInfo{ benchViewport(), 100, 200, 1000 },
  15. mnd::MandelInfo{ benchViewport(), 200, 200, 1000 },
  16. mnd::MandelInfo{ benchViewport(), 200, 200, 2000 },
  17. mnd::MandelInfo{ benchViewport(), 200, 400, 2000 },
  18. mnd::MandelInfo{ benchViewport(), 400, 400, 2000 },
  19. mnd::MandelInfo{ benchViewport(), 400, 400, 4000 },
  20. mnd::MandelInfo{ benchViewport(), 400, 800, 4000 },
  21. mnd::MandelInfo{ benchViewport(), 800, 800, 4000 },
  22. mnd::MandelInfo{ benchViewport(), 800, 800, 8000 },
  23. mnd::MandelInfo{ benchViewport(), 800, 800, 16000 },
  24. mnd::MandelInfo{ benchViewport(), 800, 1600, 16000 },
  25. mnd::MandelInfo{ benchViewport(), 1600, 1600, 16000 },
  26. mnd::MandelInfo{ benchViewport(), 1600, 1600, 32000 },
  27. mnd::MandelInfo{ benchViewport(), 1600, 1600, 64000 },
  28. mnd::MandelInfo{ benchViewport(), 1600, 3200, 64000 },
  29. mnd::MandelInfo{ benchViewport(), 3200, 3200, 64000 },
  30. mnd::MandelInfo{ benchViewport(), 3200, 3200, 128000 },
  31. mnd::MandelInfo{ benchViewport(), 3200, 3200, 256000 },
  32. mnd::MandelInfo{ benchViewport(), 3200, 3200, 512000 },
  33. mnd::MandelInfo{ benchViewport(), 3200, 3200, 1024000 },
  34. mnd::MandelInfo{ benchViewport(), 3200, 3200, 2048000 },
  35. mnd::MandelInfo{ benchViewport(), 3200, 6400, 2048000 },
  36. mnd::MandelInfo{ benchViewport(), 6400, 6400, 2048000 },
  37. mnd::MandelInfo{ benchViewport(), 6400, 6400, 4096000 },
  38. mnd::MandelInfo{ benchViewport(), 6400, 6400, 8192000 },
  39. mnd::MandelInfo{ benchViewport(), 6400, 6400, 16384000 },
  40. mnd::MandelInfo{ benchViewport(), 6400, 6400, 32768000 },
  41. mnd::MandelInfo{ benchViewport(), 6400, 6400, 65536000 },
  42. mnd::MandelInfo{ benchViewport(), 6400, 6400, 131072000 },
  43. mnd::MandelInfo{ benchViewport(), 6400, 6400, 262144000 },
  44. mnd::MandelInfo{ benchViewport(), 6400, 6400, 524288000 },
  45. mnd::MandelInfo{ benchViewport(), 6400, 6400, 1048576000 },
  46. mnd::MandelInfo{ benchViewport(), 6400, 6400, 2097152000 },
  47. };
  48. std::pair<long long, std::chrono::nanoseconds> measureMips(const std::function<std::pair<float*, long>()>& bench)
  49. {
  50. using namespace std::chrono;
  51. auto before = high_resolution_clock::now();
  52. auto [bitmap, length] = bench();
  53. auto after = high_resolution_clock::now();
  54. long long sum = 0;
  55. for (int i = 0; i < length; i++) {
  56. sum += std::floor(bitmap[size_t(i)]);
  57. }
  58. return std::make_pair(sum, duration_cast<nanoseconds>(after - before));
  59. /*
  60. double iterPerNanos = double(sum) / duration_cast<nanoseconds>(after - before).count();
  61. //printf("test took %lld millis\n", duration_cast<milliseconds>(after - before).count());
  62. //printf("test did %lld iters\n", sum);
  63. double megaItersPerSecond = iterPerNanos * 1000.0;
  64. return megaItersPerSecond;*/
  65. }
  66. double benchmark(mnd::Generator& generator)
  67. {
  68. /*mnd::MandelInfo mi;
  69. mi.bWidth = 250;
  70. mi.bHeight = 250;
  71. mi.maxIter = 4000;
  72. mi.view = benchViewport();*/
  73. int testIndex = 0;
  74. for (int i = 0; i < benches.size(); i++) {
  75. const mnd::MandelInfo& mi = benches[i];
  76. auto data = std::make_unique<float[]>(mi.bWidth * mi.bHeight);
  77. auto [iters, time] = measureMips([&generator, &mi, &data]() { generator.generate(mi, data.get()); return std::make_pair(data.get(), mi.bWidth * mi.bHeight); });
  78. //printf("benchmark lvl %d, time %d ms\n", i, time.count() / 1000 / 1000);
  79. //fflush(stdout);
  80. if (time > std::chrono::milliseconds(1000)) {
  81. testIndex = i + 2;
  82. break;
  83. }
  84. }
  85. const mnd::MandelInfo& mi = benches[(testIndex >= benches.size()) ? (benches.size() - 1) : testIndex];
  86. auto data = std::make_unique<float[]>(mi.bWidth * mi.bHeight);
  87. auto [iters, time] = measureMips([&generator, &mi, &data]() { generator.generate(mi, data.get()); return std::make_pair(data.get(), mi.bWidth * mi.bHeight); });
  88. //printf("bench time %d ms\n", time.count() / 1000 / 1000);
  89. //fflush(stdout);
  90. return double(iters) / time.count() * 1000;
  91. }
  92. #define REPORT_PERFORMANCE(name, performance) \
  93. do { std::cout << std::setw(30) << name << std::setw(10) << std::right << std::showbase << std::fixed << std::setprecision(2) << performance << std::endl; } while(0)
  94. int main()
  95. {
  96. Fixed128 a = 5.2;
  97. Fixed128 b = 2.0;
  98. Fixed128 c = a / b;
  99. std::cout << "val: " << double(c) << std::endl;
  100. mnd::MandelContext mc = mnd::initializeContext();
  101. std::cout << "Benchmarking CPU [" << mc.getCpuInfo().getBrand() << "]" << std::endl;
  102. REPORT_PERFORMANCE("float [MIps]: ", benchmark(mc.getCpuGeneratorFloat()));
  103. REPORT_PERFORMANCE("double [MIps]: ", benchmark(mc.getCpuGeneratorDouble()));
  104. REPORT_PERFORMANCE("fixed-point 128 bit [MIps]: ", benchmark(mc.getCpuGenerator128()));
  105. for (auto& device : mc.getDevices()) {
  106. std::cout << "Benchmarking Device [" << device.getName() << "]" << std::endl;
  107. if (mnd::Generator* gpuf; gpuf = device.getGeneratorFloat()) {
  108. REPORT_PERFORMANCE("float [MIps]: ", benchmark(*gpuf));
  109. }
  110. if (mnd::Generator* gpud; gpud = device.getGeneratorDouble()) {
  111. REPORT_PERFORMANCE("double [MIps]: ", benchmark(*gpud));
  112. }
  113. if (mnd::Generator* gpu128; gpu128 = device.getGenerator128()) {
  114. REPORT_PERFORMANCE("fixed-point 128 bit [MIps]: ", benchmark(*gpu128));
  115. }
  116. }
  117. /*
  118. std::cout << std::setw(30) << "float [MIps]: " << std::setw(10) << std::right << std::showbase << std::fixed << std::setprecision(2) << benchmark(mc.getCpuGeneratorFloat()) << std::endl;
  119. std::cout << std::setw(30) << "double [MIps]: " << std::setw(10) << std::right << std::showbase << std::fixed << std::setprecision(2) << benchmark(mc.getCpuGeneratorDouble()) << std::endl;
  120. std::cout << std::setw(30) << "fixed-point 128 bit [MIps]: " << std::setw(10) << std::right << std::showbase << std::fixed << std::setprecision(2) << benchmark(mc.getCpuGenerator128()) << std::endl;
  121. */
  122. }