Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
249 views
in Technique[技术] by (71.8m points)

c++ - Multithreaded program runs differently depending on the machine

I recently made a multithreaded mandelbrot set generator. I made it on my pc that has an AMD ryzen 3900x, and the more threads i add (way less than the maximum threads of my CPU) the slower it gets.

Then i run the same code on my laptop which has an Intel i7-7700HQ (which is slower and has way less threads), and it run perfectly, and even faster than it did on my desktop pc. what do you guys think is going on?

P.S.

I built the desktop pc, so maybe there could also be some configuration i missed or something like that.

Edit: here's the code

#include <mutex>
#include <windows.h>
#include <thread>
#include "SDL.h"

#define wid 800
#define hgt 800
#define maxt 8

std::mutex mtx;

long double map(long double x, long double in, long double im, long double on, long double om) { return (x - in) * (om - on) / (im - in) + on; }

void f(SDL_Window *wn, SDL_Renderer *rn, int x, int y, int maxi, long double minx, long double maxx, long double miny, long double maxy) {
    int i = 0;
    long double zr = 0, zi = 0;
    long double cr = map(x, 0, wid, minx, maxx), ci = map(y, 0, hgt, miny, maxy);
    long double rr = 0, ii = 0;
    for (i; i < maxi; i++) {
        rr = zr * zr - zi * zi + cr;
        ii = zr * zi * 2 + ci;
        zr = rr;
        zi = ii;
        if (zr * zr + zi * zi >= 4) break;
    }
    int col = i == maxi ? 0 : (int)map(i, 0, maxi, 0, 255);
    mtx.lock();
    SDL_SetRenderDrawColor(rn, col, col, col, 255);
    SDL_RenderDrawPoint(rn, x, y);
    mtx.unlock();
}

void fmand(SDL_Window *wn, SDL_Renderer *rn, int maxi, int xn, int xm, long double minx, long double maxx, long double miny, long double maxy) {
    for (int x = xn; x < xm; x++) {
        for (int y = 0; y < hgt; y++) {
            f(wn, rn, x, y, maxi, minx, maxx, miny, maxy);
        }
    }
}

int main(int argc, char *argv[]) {
    long double minx = -2, maxx = 2, zf = 0.96;
    long double miny = -2, maxy = 2;
    long double xoff = 0, yoff = 0;
    int maxi = 256;
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window *wn = SDL_CreateWindow("Mandelbrot", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, wid, hgt, 0);
    SDL_Renderer *rn = SDL_CreateRenderer(wn, -1, 0);
    SDL_Event event;
    SDL_SetRenderDrawColor(rn, 0, 0, 0, 255);
    SDL_RenderClear(rn);
    while (1) {
        SDL_RenderPresent(rn);
        if (SDL_PollEvent(&event) && event.type == SDL_QUIT) break;
        if (GetKeyState('Q') & 0x8000) break;
        if (GetKeyState('W') & 0x8000) yoff -= 0.1 * zf;
        if (GetKeyState('S') & 0x8000) yoff += 0.1 * zf;
        if (GetKeyState('A') & 0x8000) xoff -= 0.1 * zf;
        if (GetKeyState('D') & 0x8000) xoff += 0.1 * zf;
        if (GetKeyState('Z') & 0x8000) zf *= 0.7;
        if (GetKeyState('U') & 0x8000) zf /= 0.7;
        if (GetKeyState(VK_OEM_PLUS) & 0x8000) maxi *= 1.2;
        if (GetKeyState(VK_OEM_MINUS) & 0x8000 && maxi > 64) maxi /= 1.2;
        //fmand(wn, rn, maxi, 0, wid, minx * zf + xoff, maxx * zf + xoff, miny * zf + yoff, maxy * zf + yoff);
        std::thread t[maxt];
        for (int i = 0; i < maxt; i++)
            t[i] = std::thread(fmand, wn, rn, maxi, (int)(wid / maxt * i), (int)(wid / maxt * (i+1)), minx * zf + xoff, maxx * zf + xoff, miny * zf + yoff, maxy * zf + yoff);
        for (int i = 0; i < maxt; i++)
            t[i].join();
    }
    return 0;
}

And regarding the compiler i actually use the stardard compiler options that Visual Studio 2019 has, I didn't modify anithing except that i added an -O2 to improve performance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...