Skip to content

kozakaron/Mandelbrot-set-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mandelbrot set C++

Ez a program kirajzolja a Mandelbrot halmazt különböző hardvarre optimalizált módszerekkel. image

Futtatás

Tartalom

  • CPU mappa - Az OpenCV-vel írt megoldás, ami valós időben kirajzolja a képet
    • mandelbrot window.cpp - (main) megjelenítés, keyboard input
    • otherFunctions.h - includeok, chrono library-n alapuló időméárő osztály, colormapek
    • naivSolution.h, naivMultiThread.h, cpuOptSolution.h, cpuOptMultiThread.h - Mandelbrot halmaz kirajzolása különböző módokon optimalzálva (lásd lentebb)
    • CPU.zip - Visual Studio teljes projekt (a fenti fáljokkal)
  • GPU mappa - A CUDA-ban írt megoldást, ami pont ugyanolyan képet készít, de azt nem tudja kirajzolni, helyette bitmap (.bmp) formátumban menti
    • kernel.cu - A main file, a kirajzolással
    • Header.cuh - Header a colormappel és mentést végző függvényekkel
    • DeviceProperties.cuh - A gpu tulajdonságainak kiírásához (A BME HDR Tanszék tulajdona)
  • colormap stealer.ipynb - A Python Matplotlib könyvtárának bármely colormapjét el tudja "lopni"

Fordítás

Le lehet tölteni a teljes VS projektet (GPU.zip, és CPU.zip), ami kicsomagolás után szerkeszthető Visual Studioban, a megfelekő könyvtárak telepítése után

  • Le kell tölteni Agner Fog Vector Class Library-ját. (VCL manual)
  • Telepíteni kell az OpenCV-t
  • Állítsd a fordítót x64-re, C++17-re, és Realeasre (Debug módban a VCL használhatatlanul lassú)
  • A GPU-s megoldáshoz telepíten kell a CUDA-t

Beállítások

A CPU-s kódban lehet állítani:

  • felbontás: (mandelbrot window.cpp 18. sor) Mat image = Mat::zeros(1024, 2048, CV_8UC3); // Legyen a szélesség (2048) a 16 többszöröse
  • kirajzolás módja: (mandelbrot window.cpp 33-36. sor) Pontosan az egyik kirajzoló függvény ne legyen kikommentezve
  • float használata double helyett: (otherFunctions.h 15. sor) definiáld a USE_FLOAT konstanst, ha floatot szeretnél. (Így a maximális nagyítás 10^-14 helyett 10^-5; a VCL-es kirajzolás sokkal gyorsabb; összehasonlítható majd a GPU-val)
  • colormap: (otherFunctions.h, 15-20. sor) definiáld a VIRIDIS, GIST_RAINBOW, HOT, PLASMA konstansok valamelyikét, vagy egyiket se, hogy grayscale képet kapj. A colormapeket a Python Matplotlib könyvtárából szedtem ki a colormap stealer.ipynb -vel

A GPU-s kódban a felbontás a const int width, height paraméterekkel állítható. A colormap HOT. Double használatát a #define NUMBER float cseréjével érheted el.

Irányítás

A kép változtatható a billentyűzettel, amennyiben az OpenCV ablaka az aktív

  • Mozgás: asdw
  • Nagyítás: qe
  • Iterációs limit állítása: 12
  • Alaphelyzetbe állás: r
  • Kilépés: ESC
  • Renderelés: bármely billenytyű, kivéve az ESC

A konzolban megjeleník a nagyítás, iterációs limit, és a renderidő

Optimalizálás

A különböző futási idők: (Alapértelmezett kép, legalább 10 képkockából átlagolva, ezredmásodpercben)
Computer specs:
Intel Core i5-4310M @ 2.70GHz
2 cores; 4 threads; 2.70-3.40 GHz
cache 128 KB, 512 KB, 3 MB;
AVX2 --> (256 bit vector registers)

[millisec] float double
naiv 562 432
naiv multithread 182 143
CPU optimalized 142 271
CPU multi thread 59 129

Computer specs:
Intel Core i5-6500 CPU @ 3.20GHz 4 cores; 4 threads; 3.20-3.60 GHz
cache 32 KB, 256 KB, 6 MB;
AVX2 --> (256 bit vector registers)

NVIDIA GeForce GTX 1050 Ti 4095 Mb memory 2048 threads, 32 warp size FP32 (float) performance: 2.138 TFLOPS FP64 (double) performance: 66.82 GFLOPS (1:32)

[millisec] float double
naiv 641 494
naiv multithread 192 119
CPU optimalized 123 244
CPU multi thread 43 66
GPU 20 20

Megoldások:

  • Naiv megoldás: Egyszálon fut, beépített (int, double) típusokat használ. Ez a leglasabb.
  • Multithread naiv megoldás: Kihasználja az összes szálat (thread library), de ugyanúgy az alap típusokat (int, double) használja. Minden szál aktív, amíg van olyan sor, amit nem kezdett el renderelni egy másik szál. Nagyjából 3,3-szor gyorsabb a naiv megoldásnál (4 mag, 4 szál) float esetén, és 4,2-szer double esetén.
  • CPU-ra optimalizált megoldás: Kihasználja a Vector Class Library 256 bites vektor regisztereit (4 double vagy 8 float), azaz Single Intstuction Multiple Data (SIMD) elven gyorsítja a futást. Floattal kb 5,2-szer gyorsabb, doublelel pedig 2-szer.
  • CPU-ra optimalizált multithread megoldás: A fentiekhez hasonlóan vektor regisztert használ, és többszálon fut. Float esetén 14,9-ször, double esetén 7,5-szor gyorsabb.
  • GPU-ra írt megoldás: Minden pixelre (~ 2 millió) külön CUDA magot hív meg. (Összesen 2048 van)

Galéria

image Az iterációs limit állításának hatása a képre. image A különböző colormapek. image image A szám felbontási limitje (floatnál ~10^-5; doublenál ~10^-15)

About

Draw the Mandelbrot set with OpenCV. Make it as fast as possible with CPU and GPU optimalizations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors