Commit 8f47876d by FritzFlorian

Add standard divide and conquer matrix multiplication test for comparison.

parent 92ee564c
Pipeline #1502 passed with stages
in 4 minutes 13 seconds
......@@ -8,7 +8,8 @@ add_library(benchmark_base STATIC
include/benchmark_base/matrix.h
include/benchmark_base/unbalanced.h src/unbalanced.cpp
include/benchmark_base/range.h
include/benchmark_base/fib.h)
include/benchmark_base/fib.h
include/benchmark_base/matrix_div_conquer.h)
target_include_directories(benchmark_base
PUBLIC
......
#ifndef COMPARISON_BENCHMARKS_BASE_MATRIX_DIV_CONQUER_H
#define COMPARISON_BENCHMARKS_BASE_MATRIX_DIV_CONQUER_H
#include <array>
namespace comparison_benchmarks {
namespace base {
namespace matrix_div_conquer {
const int MATRIX_SIZE = 128;
const int CUTOFF_SIZE = 8;
const int NUM_ITERATIONS = 100;
const int WARMUP_ITERATIONS = 10;
// Helpers to directly index into blocked matrices
const size_t MAX_SIZE = 128;
std::array<std::array<size_t, MAX_SIZE>, MAX_SIZE> BLOCK_LOOKUP; // ROW, COLUMN
void fill_block_lookup(size_t size = MAX_SIZE) {
if (size <= 1) {
BLOCK_LOOKUP[0][0] = 0;
return;
}
fill_block_lookup(size / 2);
size_t elements_per_quarter = (size / 2) * (size / 2);
for (size_t row = 0; row < size / 2; row++) {
for (size_t column = 0; column < size / 2; column++) {
BLOCK_LOOKUP[row][size / 2 + column] = BLOCK_LOOKUP[row][column] + elements_per_quarter;
BLOCK_LOOKUP[size / 2 + row][column] = BLOCK_LOOKUP[row][column] + 2 * elements_per_quarter;
BLOCK_LOOKUP[size / 2 + row][size / 2 + column] = BLOCK_LOOKUP[row][column] + 3 * elements_per_quarter;
}
}
}
class blocked_matrix_view {
public:
blocked_matrix_view(double *data, size_t size) : data_{data}, size_{size} {}
void fill_default_data() {
for (size_t row = 0; row < size_; row++) {
for (size_t column = 0; column < size_; column++) {
at(row, column) = row;
}
}
}
blocked_matrix_view quadrant_1_1() {
size_t elements_per_quarter = (size_ / 2) * (size_ / 2);
return blocked_matrix_view(data_ + 0 * elements_per_quarter, size_ / 2);
}
blocked_matrix_view quadrant_1_2() {
size_t elements_per_quarter = (size_ / 2) * (size_ / 2);
return blocked_matrix_view(data_ + 1 * elements_per_quarter, size_ / 2);
}
blocked_matrix_view quadrant_2_1() {
size_t elements_per_quarter = (size_ / 2) * (size_ / 2);
return blocked_matrix_view(data_ + 2 * elements_per_quarter, size_ / 2);
}
blocked_matrix_view quadrant_2_2() {
size_t elements_per_quarter = (size_ / 2) * (size_ / 2);
return blocked_matrix_view(data_ + 3 * elements_per_quarter, size_ / 2);
}
double &at(size_t row, size_t column) {
return data_[BLOCK_LOOKUP[row][column]];
}
double *get_data() {
return data_;
}
private:
double *data_;
size_t size_;
};
void multiply_naive(size_t size, blocked_matrix_view &result, blocked_matrix_view &a, blocked_matrix_view &b) {
for (size_t i = 0; i < size; i++) {
for (size_t j = 0; j < size; j++) {
result.at(i, j) = 0;
}
for (size_t j = 0; j < size; j++) {
for (size_t k = 0; k < size; k++) {
result.at(i, j) += a.at(i, k) * b.at(k, j);
}
}
}
}
}
}
}
#endif // COMPARISON_BENCHMARKS_BASE_MATRIX_DIV_CONQUER_H
......@@ -154,7 +154,6 @@ template<typename Function>
void scheduler::spawn_internal(Function &&lambda) {
if (thread_state::is_scheduler_active()) {
thread_state &spawning_state = thread_state::get();
scheduler &scheduler = spawning_state.get_scheduler();
base_task *last_task = spawning_state.get_active_task();
base_task *spawned_task = last_task->next_;
......
......@@ -60,8 +60,7 @@ class strain_local_resource {
};
strain_local_resource(unsigned num_threads,
unsigned depth) : local_items_() {
local_items_.reserve(num_threads);
unsigned depth) : local_items_(num_threads) {
for (unsigned thread_id = 0; thread_id < num_threads; thread_id++) {
local_items_[thread_id].reserve(depth);
for (unsigned i = 0; i < depth; i++) {
......
......@@ -8,6 +8,7 @@
#include "pls/algorithms/reduce.h"
#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/strain_local_resource.h"
#include "pls/internal/helpers/range.h"
#include "pls/internal/helpers/member_function.h"
......@@ -28,6 +29,9 @@ static void serial(Function &&function) {
scheduler::serial(std::forward<Function>(function));
}
// strain local resource support (rather low-level)
using internal::scheduling::strain_local_resource;
// general helpers that can be handy when using PLS
template<class C, typename R, typename ...ARGS>
using member_function = internal::helpers::member_function<C, R, ARGS...>;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment