main.cpp 3.12 KB
Newer Older
1 2 3 4 5
#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/parallel_result.h"
#include "pls/internal/scheduling/scheduler_memory.h"
#include "pls/algorithms/for_each.h"
using namespace pls::internal::scheduling;
6

7 8
#include <chrono>

9 10 11 12 13 14 15
const int MATRIX_SIZE = 128;

template<typename T, int SIZE>
class matrix {
 public:
  T data[SIZE][SIZE];

16
  explicit matrix(T i = 1) {
17 18 19
    std::fill(&data[0][0], &data[0][0] + SIZE * SIZE, i);
  }

20 21
  parallel_result<int> multiply(const matrix<T, SIZE> &a, const matrix<T, SIZE> &b) {
    return pls::algorithm::for_each_range(0, SIZE, [&](int i) {
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
      this->multiply_column(i, a, b);
    });
  }

 private:
  void multiply_column(int i, const matrix<T, SIZE> &a, const matrix<T, SIZE> &b) {
    for (int j = 0; j < SIZE; ++j) {
      data[i][j] = 0;
    }
    for (int k = 0; k < SIZE; ++k) {
      for (int j = 0; j < SIZE; ++j) {
        data[i][j] += a.data[i][k] * b.data[k][j];
      }
    }
  }
};

void fill_with_data(matrix<double, MATRIX_SIZE> &a, matrix<double, MATRIX_SIZE> &b) {
  // Fill in some data...
  for (int i = 0; i < MATRIX_SIZE; i++) {
    for (int j = 0; j < MATRIX_SIZE; j++) {
      a.data[i][j] = i;
      b.data[i][j] = j;
    }
  }
}

49 50 51 52 53 54 55 56
static constexpr int NUM_ITERATIONS = 1000;
constexpr size_t NUM_THREADS = 3;

constexpr size_t NUM_TASKS = 128;

constexpr size_t NUM_CONTS = 128;
constexpr size_t MAX_CONT_SIZE = 512;

57 58 59 60 61 62 63
int main() {
  PROFILE_ENABLE
  matrix<double, MATRIX_SIZE> a;
  matrix<double, MATRIX_SIZE> b;
  matrix<double, MATRIX_SIZE> result;
  fill_with_data(a, b);

64 65 66 67
  static_scheduler_memory<NUM_THREADS,
                          NUM_TASKS,
                          NUM_CONTS,
                          MAX_CONT_SIZE> static_scheduler_memory;
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  scheduler scheduler{static_scheduler_memory, NUM_THREADS};

  auto start = std::chrono::steady_clock::now();
  for (int i = 0; i < NUM_ITERATIONS; i++) {
    scheduler.perform_work([&]() {
      PROFILE_MAIN_THREAD;
      return scheduler::par([&]() {
        return result.multiply(a, b);
      }, []() {
        return parallel_result<int>{0};
      }).then([](int, int) {
        return parallel_result<int>{0};
      });
    });
  }
  auto end = std::chrono::steady_clock::now();
  std::cout << "Framework:  " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
            << std::endl;
87 88 89 90
}

//int main() {
//  PROFILE_ENABLE
91 92
//  pls::malloc_scheduler_memory my_scheduler_memory{8, 2u << 18u};
//  pls::scheduler scheduler{&my_scheduler_memory, 4};
93 94 95 96 97 98 99
//
//  matrix<double, MATRIX_SIZE> a;
//  matrix<double, MATRIX_SIZE> b;
//  matrix<double, MATRIX_SIZE> result;
//  fill_with_data(a, b);
//
//  scheduler.perform_work([&] {
100
//    auto start_time = std::chrono::high_resolution_clock::now();
101
//    PROFILE_MAIN_THREAD
102
//    for (int i = 0; i < 10000; i++) {
103 104 105
//      PROFILE_WORK_BLOCK("Top Level")
//      result.multiply(a, b);
//    }
106 107 108
//    auto end_time = std::chrono::high_resolution_clock::now();
//    long time = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time).count();
//    std::cout << "Runtime: " << time << "us" << std::endl;
109 110 111 112
//  });
//
//  PROFILE_SAVE("test_profile.prof")
//}
113