From c79412bdab70f67f63e25899a19df4477af6adf3 Mon Sep 17 00:00:00 2001 From: koma Date: Tue, 5 Jul 2022 23:22:01 +0200 Subject: [PATCH] implemented working multithreading --- graphics.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++-------- mandelbrot.cpp | 32 ++++++++++++++++++++--- mandelbrot.h | 6 +++-- 3 files changed, 93 insertions(+), 16 deletions(-) diff --git a/graphics.cpp b/graphics.cpp index 6982408..35135b5 100644 --- a/graphics.cpp +++ b/graphics.cpp @@ -110,8 +110,8 @@ void Graphics::plot(Mandelbrotc const &m) // } // } - for (uint32_t i = 0; i < m.screen.size(); i+=2) { - for (uint32_t j = 0; j < m.screen[0].size(); j+=2) { + for (uint32_t i = 0; i < m.s.x; i++) { + for (uint32_t j = 0; j < m.s.y; j++) { uint8_t color = 255 - (m.screen[i][j]*255/m.max_iter); SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); SDL_RenderDrawPoint(renderer, (int)i, (int)j); @@ -128,10 +128,13 @@ void Graphics::mainLoop() this->from = Vec2mp(fx, fy); this->to = Vec2mp(tx, ty); + bool mouseDown = false; + Vec2i m_start = Vec2i(0, 0); + Vec2i m_end = Vec2i(0, 0); Mandelbrotc m = Mandelbrotc(from, to, Vec2i(this->w, this->h), 100); - m.thread_count = 5; - m.start_threads(); + m.thread_count = 16; + m.start_threads(true); while (this->running) { @@ -160,21 +163,67 @@ void Graphics::mainLoop() this->to.y += 0.2; } break; + case SDL_MOUSEBUTTONDOWN: + if (mouseDown) + break; + mouseDown = true; + m_start.x = event.button.x; + m_start.y = event.button.y; + break; + case SDL_MOUSEBUTTONUP: + mouseDown = false; + break; case SDL_MOUSEMOTION: + m_end.x = event.motion.x; + m_end.y = event.motion.y; break; } } - - std::cout << "mainloop range " << this->from.x << std::endl; - std::cout << "mainloop range " << this->from.y << std::endl; - std::cout << "mainloop range " << this->to.x << std::endl; - std::cout << "mainloop range " << this->to.y << std::endl; - //this->plot(this->from, this->to); + + if (mouseDown) { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + if (m_start.x < m_end.x) { + for (int i = m_start.x; i < m_end.x; i++) { + SDL_RenderDrawPoint(renderer, i, m_start.y); + SDL_RenderDrawPoint(renderer, i, m_end.y); + } + } else { + for (int i = m_end.x; i < m_start.x; i++) { + SDL_RenderDrawPoint(renderer, i, m_start.y); + SDL_RenderDrawPoint(renderer, i, m_end.y); + } + } + if (m_start.y < m_end.y) { + for (int i = m_start.y; i < m_end.y; i++) { + SDL_RenderDrawPoint(renderer, m_start.x, i); + SDL_RenderDrawPoint(renderer, m_end.x, i); + } + } else { + for (int i = m_end.y; i < m_start.y; i++) { + SDL_RenderDrawPoint(renderer, m_start.x, i); + SDL_RenderDrawPoint(renderer, m_end.x, i); + } + } + } - std::cout << "done" << std::endl; + // std::cout << "mainloop range " << this->from.x << std::endl; + // std::cout << "mainloop range " << this->from.y << std::endl; + // std::cout << "mainloop range " << this->to.x << std::endl; + // std::cout << "mainloop range " << this->to.y << std::endl; + + m.start_threads(false); + this->plot(m); + m.stop_threads(); + + // std::cout << "done" << std::endl; SDL_RenderPresent(renderer); SDL_SetRenderDrawColor(this->renderer, 255, 255, 255, 255); + SDL_RenderClear(renderer); + SDL_Delay(100); + if (m.done) + exit(1); } + m.stop_threads(); } diff --git a/mandelbrot.cpp b/mandelbrot.cpp index 597958f..2142c0b 100644 --- a/mandelbrot.cpp +++ b/mandelbrot.cpp @@ -9,26 +9,52 @@ Mandelbrotc::Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint3 : f(f), t(t), s(s), max_iter(mi) { this->threads = std::vector(); - this->screen = std::vector>(); + //this->screen = std::vector>(); + this->screen = new uint8_t*[s.x]; + for(int i = 0; i < s.x; ++i) + this->screen[i] = new uint8_t[s.y]; + + this->done = false; } -void Mandelbrotc::start_threads() +void Mandelbrotc::start_threads(bool first) { + if (!this->done && !first) + return; + Mandelbrotc const &m = *this; + for (int i = 0; i < this->thread_count; i++) { + std::thread t = std::thread(&Mandelbrotc::calc, this, i); + this->threads.push_back(std::move(t)); + std::cout << "thread created" << std::endl; + } + this->done = false; } +void Mandelbrotc::stop_threads() +{ + for (int i = 0; i < this->thread_count; i++) { + while (!this->threads[i].joinable()) + this->threads[i].join(); + } +} void Mandelbrotc::calc(const uint8_t tid) { mpreal x, y; + std::vector v = std::vector(); for(double i = tid; i < this->s.x; i+=this->thread_count) { for(double j = 0; j < this->s.y; j++) { x = (mpfr::abs(this->f.x - this->t.x) * (i / this->s.x)) + this->f.x; y = (mpfr::abs(this->f.y - this->t.y) * (j / this->s.y)) + this->f.y; - this->screen[i][j] = mandelbrot(Vec2mp(x, y)); + this->screen[(int)i][(int)j] = this->mandelbrot(Vec2mp(x, y)); } } + + std::cout << "thread " << tid << " done" << std::endl; + if (tid == thread_count-1) + this->done = true; } uint32_t Mandelbrotc::mandelbrot(const Vec2mp &n) diff --git a/mandelbrot.h b/mandelbrot.h index 7706811..285dd68 100644 --- a/mandelbrot.h +++ b/mandelbrot.h @@ -15,11 +15,13 @@ public: uint8_t thread_count; std::vector threads; Vec2i s; - std::vector> screen; + //std::vector> screen; + uint8_t **screen; + bool done; uint32_t max_iter; Mandelbrotc(Vec2mp const &f, Vec2mp const &t, Vec2i const &s, uint32_t mi); - void start_threads(); + void start_threads(bool first); void stop_threads(); uint32_t mandelbrot(const Vec2mp &n); void calc(const uint8_t tid);