/* * Programming Techniques for Scientific Simulations I * HS 2019 * Exercise 10 */ #include #include #include #include #include "matrix_multiplication.hpp" double benchmark(function_t f, matrix_t const & A, matrix_t const & B, matrix_t & C, std::size_t N) noexcept { for (std::size_t i = 0; i < N * N; ++i) { C[i] = 0; } auto start = std::chrono::high_resolution_clock::now(); f(A, B, C, N); auto end = std::chrono::high_resolution_clock::now(); return std::chrono::duration(end - start).count(); } int main() { std::mt19937 gen; std::uniform_real_distribution dis(0, 1); { constexpr int N = 16; constexpr double tolerance = 1e-6; matrix_t A(N * N); matrix_t B(N * N); for (std::size_t j = 0; j < N; ++j) { for (std::size_t i = 0; i < N; ++i) { A[i + j * N] = dis(gen); B[i + j * N] = dis(gen); } } #define TEST(f) do { \ matrix_t C(N * N); \ for (int i = 0; i < N * N; ++i) { \ C[i] = 0; \ } \ f(A, B, C, N); \ for (int i = 0; i < N; ++i) { \ for (int j = 0; j < N; ++j) { \ if (std::abs(C0[i + j * N] - C[i + j * N]) > tolerance) { \ std::cerr << #f << " incorrect" << '\n' << "C0" << '\n'; \ for (int j = 0; j < N; ++j) { \ for (int i = 0; i < N; ++i) { \ std::cerr << C0[i + j * N] << ' '; \ } \ std::cerr << '\n'; \ } \ std::cerr << "C" << '\n'; \ for (int j = 0; j < N; ++j) { \ for (int i = 0; i < N; ++i) { \ std::cerr << C[i + j * N] << ' '; \ } \ std::cerr << '\n'; \ } \ exit(1); \ } \ } \ } \ } while (false) matrix_t C0(N * N); mm0(A, B, C0, N); TEST(mm0); TEST(mm1); TEST(mm2); TEST(mm3); TEST(mm_blas); TEST(mm_eigen); } constexpr int runs = 10; #define BENCHMARK(f) do { \ for (int i = 0; i < runs; ++i) { \ auto time = benchmark(f, A, B, C, N); \ std::cout << #f << ',' << N << ',' << time << std::endl; \ } \ } while (false) std::cout << "function,size,time" << std::endl; for (int N = 4; N <= 1024; N *= 2) { matrix_t A(N * N); matrix_t B(N * N); matrix_t C(N * N); for (std::size_t i = 0; i < N * N; ++i) { A[i] = dis(gen); B[i] = dis(gen); } BENCHMARK(mm0); BENCHMARK(mm1); BENCHMARK(mm2); BENCHMARK(mm3); BENCHMARK(mm_blas); BENCHMARK(mm_eigen); } #undef BENCHMARK }