Visualiseur Mandelbrot

Programmation d'applications complexes
Avatar de l’utilisateur
Guillot
Messages : 529
Inscription : jeu. 25/juin/2015 16:18

Visualiseur Mandelbrot

Message par Guillot »

salut tout le monde

un petit visualiseur de la fonction de Mandelbrot
il est tres rapide, les calculs sont fait en ASM (merci Manababel !)
il est multithread

en appuyant sur [F1] vous aurez même droit à une visite guidée !

enlever le débogueur !!
et activer la gestion des treads dans les options de compilation (pas nécéssaire chez moi ??)

Code : Tout sélectionner

EnableExplicit

Global limit=255,ex=1280,ey=720,     i,x,y,z,b,dx,dy,pass=-1,cpt=4,t
Global.d apx,px, apy,py,ascale,scale

Global Dim pal.l(limit)
Global Dim Bmp.l(ey - 1, ex - 1)

Global ndt=CountCPUs(#PB_System_ProcessCPUs )
Global Dim Thread(ndt)

Procedure ColorBlend(color1.l, color2.l, blend.f)
    Protected r.w,g.w,b.w,a.w
    r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
    g=Green(color1) + (Green(color2) - Green(color1)) * blend
    b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
    a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
    ProcedureReturn  RGBA(r,g,b,a)
EndProcedure

Procedure InitPalette(n=16,Cont=0)
    Protected i,j,c1,c2
    c2=Random($ffffff)
    For j = 0 To limit/n
        If Cont:c1=c2:Else:c1=Random($ffffff):EndIf
        c2=Random($ffffff)
        For i=0 To n-1
            pal(j*n+i) =ColorBlend(c1,c2, i/ n) | $ff000000
        Next
    Next
    pal(limit) = $ff000000
EndProcedure

Procedure mandelbrotx4(a.d,b.d,scale.d,Array col.q(1))
    Protected cp.q,fo.d,add.q,     i,t,c
    Protected infinity.f=4
    Dim tab.d(4)
    cp=limit
    fo=infinity
    add=1
    For i=0 To 3
        tab(i)=a
        a+scale
    Next

    t=@tab()
    c=@col()
    !mov rdx,[p.v_t]
    !VPBROADCASTQ ymm8,[p.v_add] ;1  1  1  1
    !VBROADCASTSD ymm7,[p.v_fo] ; 4  4  4  4
    !vmovupd ymm0,[rdx] ;         a1 a2 a3 a4
    !VBROADCASTSD ymm1,[p.v_b] ;  b  b  b  b
    !vmovupd ymm2,ymm0 ; c=a
    !vmovupd ymm3,ymm1 ; d=b
    !vpxor ymm9,ymm9,ymm9
   
    !xor rax,rax
    !boucle:
   
    !vmovupd ymm4,ymm0
    !vmovupd ymm5,ymm1
    !vmulpd ymm4,ymm4,ymm4 ; aa = a * a
    !vmulpd ymm5,ymm5,ymm5 ; bb = b * b
   
    !vmovupd ymm6,ymm4
    !vaddpd ymm6,ymm6,ymm5
   
    ;If (aa + bb) > 4.0:Goto fin:EndIf
    !vcmpltpd ymm6,ymm6,ymm7
    !vmovmskpd rcx,ymm6
    !vandpd  ymm6,ymm6,ymm8 ; and 1
    !vpaddq ymm9,ymm9,ymm6  ; add 1
    !Or rcx,rcx
    !jz fin
   
    ;x1 = 2 * x0 * x1 + x3
    !vmulpd ymm1,ymm1,ymm0 ; b*a
    !vaddpd ymm1,ymm1,ymm1 ; (a*b)*2
    !vaddpd ymm1,ymm1,ymm3 ; (a*b*2)+d
   
    ;x0 = x4 - x5 + c
    !vmovupd ymm0,ymm4 ; a = aa
    !vsubpd ymm0,ymm0,ymm5 ; a = aa - bb
    !vaddpd ymm0,ymm0,ymm2 ;  a = aa - bb + c
   
    !inc rax
    !cmp rax,[p.v_cp]
    !jb boucle
   
    !fin:
   
    !mov rdx,[p.v_c]
    !vMOVDQU [rdx],ymm9
   
    !VZEROALL
   
EndProcedure

Procedure mandelbrot(num)
    Protected i,j,di,dj,jdeb,jfin  ,x.d,y.d
    Dim col.q(4)
    
    jdeb=ey/ndt*num
    jfin=ey/ndt*(num+1)
    di=pass & 1
    dj=pass >>1
    For j=jdeb+dj To jfin-1 Step 2
        y=py+(j -ey/2)*scale
        x=px+(di-ex/2)*scale
        For i=di To ex-1 Step 8
            mandelbrotx4(x, y,scale*2,col())
            bmp(j,i+0)=pal(col(0))
            bmp(j,i+2)=pal(col(1))
            bmp(j,i+4)=pal(col(2))
            bmp(j,i+6)=pal(col(3))
            x+scale*8
        Next
    Next
EndProcedure

InitSprite()
InitKeyboard()
InitMouse()
OpenWindow(0, 0, 0,ex,ey, " Mandelbrot - Use mouse + wheel - LMB to change colors - [F1] Animation (clic to stop) - [Esc] Quit",#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, ex, ey)
;OpenScreen(ex,ey,32,"")

InitPalette()
scale=2/ey

Structure d3
    x.d
    y.d
    z.d
EndStructure

Define auto=0,n,speed.f=0.01,ncible=-1
Dim cible.d3(100)
Macro defcible(vx,vy,vz)
    ncible+1
    cible(ncible)\x=vx
    cible(ncible)\y=vy
    cible(ncible)\z=vz
EndMacro

defcible(0,0,scale)
defcible(-1.74824670606330,-0.00000929287120,0.0000000000004)
defcible(-1.47371049186618,-0.00118606043680,0.00000000000402)
defcible(-0.10494709460288,0.92785703871758,0.00000000000002)
defcible(-0.17030719754610,-1.04455558192402,0.00000000000002)
defcible(-1.02351647109090,-0.28038897116474,0.000000000000003)
defcible(-1.24608830915113,-0.32550803613228,0.000000000000072)
defcible(-1.25403231646337,0.38483487689992,0.000000000000183)
defcible(-1.24165790231311,0.32354681010716,0.00000000000001)
defcible(0.39271500274068,-0.36734653571715,0.000000000000044)
defcible(-1.48126951978746,-0.00269131747118,0.00000000000004)
defcible(-1.99909584429894,-0.00000007963938,0.00000000000090)
n=Random(ncible,1)
CreateSprite(0,32,32):StartDrawing(SpriteOutput(0)):LineXY(0,15,31,15,$ffffffff):LineXY(15,0,15,31,$ffffffff):StopDrawing()
MouseLocate(ex/2,ey/2)
Repeat  
    WindowEvent()
    ExamineMouse()
    ExamineKeyboard()
    If MouseButton(2):InitPalette():cpt=4:EndIf 
    If MouseButton(3):SetClipboardText("defcible("+StrD(px,14)+","+StrD(py,14)+","+StrD(scale,14)+")"):End:EndIf 
    ascale=scale
    apx=px
    apy=py
    If auto
        If Abs(Log(scale)-Log(cible(n)\z))<0.1:If n:n=0:Else:n=Random(ncible,1):InitPalette():EndIf:Debug n:EndIf
        px+(cible(n)\x-px)*speed*1.1
        py+(cible(n)\y-py)*speed*1.1
        scale+(cible(n)\z-scale)*speed
        If MouseButton(1):auto=0:EndIf
    Else
        x=MouseX()
        y=MouseY()
        scale=scale*(1-0.1*MouseWheel())
        px-(x-ex/2)*(scale-ascale)
        py-(y-ey/2)*(scale-ascale)
        If MouseButton(1):px-MouseDeltaX()*scale:py-MouseDeltaY()*scale:EndIf         
        If KeyboardReleased(#PB_Key_F1):auto=1:scale=cible(n)\z:EndIf
    EndIf
    If ascale<>scale Or apx<>px Or apy<>py:cpt=4:EndIf
    If cpt
        cpt-1
        pass=(pass+1) & 3
;         t=ElapsedMilliseconds()
        For i=0 To ndt-1:Thread(i)=CreateThread(@mandelbrot(),i):Next
        For i=0 To ndt-1:If Thread(i) : WaitThread(thread(i)):EndIf:Next
        ;ndt=1:mandelbrot(0)
        ;t=ElapsedMilliseconds()-t
    EndIf
    StartDrawing(ScreenOutput())
    CopyMemory(@bmp(0,0),DrawingBuffer(),ex*ey*4)
    DrawingMode(#PB_2DDrawing_Transparent )
    DrawText(10,10,"Scale  " + StrD(scale,14))
    DrawText(10,30,"X  "+StrD(px,14))
    DrawText(10,50,"Y  "+StrD(py,14))
    ;DrawText(10,70,Str(t))
    StopDrawing()
    DisplayTransparentSprite(0,x-15,y-15)
    FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape)
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Visualiseur Mandelbrot

Message par Ar-S »

C'est top.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
SPH
Messages : 4726
Inscription : mer. 09/nov./2005 9:53

Re: Visualiseur Mandelbrot

Message par SPH »

Super rapide :idea:
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Visualiseur Mandelbrot

Message par Micoute »

Curieusement, à la ligne 47, j'ai [ERREUR] Instruction illégale. (exécution de données binaires?)
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: Visualiseur Mandelbrot

Message par manababel »

Tres bien .

attention , le programme bug si on change de resolution.
Avatar de l’utilisateur
Guillot
Messages : 529
Inscription : jeu. 25/juin/2015 16:18

Re: Visualiseur Mandelbrot

Message par Guillot »

à Micoute :
ça fonctionne pas sur sur PB 32 bit, c'est ton cas ?

à Manababel :
à chaque passe je met à jour 1 pixel sur 4, c'est un peu crado, mais c'est plus fluide
quelle résolution fait planter ?
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: Visualiseur Mandelbrot

Message par manababel »

les résolutions "bâtards"

exemple 1281x723
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Visualiseur Mandelbrot

Message par venom »

Chez moi j'ai la même erreur que Micoute en 64 bits. Mon ordi portable a en effet une côte "bâtards"
1366x768
Voici l'erreur que j'obtiens en 32 bits avec PB 5.72 thread cocher ou non:
Image







@++
Dernière modification par venom le sam. 24/oct./2020 20:39, modifié 5 fois.
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Visualiseur Mandelbrot

Message par Micoute »

Guillot a écrit :à Micoute :
ça fonctionne pas sur sur PB 32 bit, c'est ton cas ?
J'ai essayé avec les 2 systèmes, mais c'est pas mieux.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Visualiseur Mandelbrot

Message par venom »

Micoute tu as la même erreur que moi en 32 bits ? Quel est ta résolution d'écran ?






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: Visualiseur Mandelbrot

Message par GallyHC »

Bonjour,

Pour moi > "Instruction illégale. (exécution de données binaires?)" à la ligne "c=@col()".

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Visualiseur Mandelbrot

Message par venom »

GallyHC a écrit :Bonjour,

Pour moi > "Instruction illégale. (exécution de données binaires?)" à la ligne "c=@col()".

Cordialement,
GallyHC
Oui comme moi avec le debugger actif. Et avec le debugger inactif, il y a un messagerequester. Voir image plus haut







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Visualiseur Mandelbrot

Message par Micoute »

venom a écrit :Micoute tu as la même erreur que moi en 32 bits ? Quel est ta résolution d'écran ?
2560x1080, mais c'est sur la même ligne.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: Visualiseur Mandelbrot

Message par manababel »

Je me permets de répondre à la place de Guillot.

Si la description de vos cpu sont toujours d'actualité, le programme ne fonctionne pas.
Il faut un cpu avec les instructions 'AVX2'.

le P6200 ne va qu'au 'SSE3'
le le FX 6300 au 'AVX'

voici une procédure compatible 'AVX'

Code : Tout sélectionner

Procedure mandelbrotx4(a.d,b.d,scale.d,Array col.q(1))
    Protected cp.q,fo.d,add.q,     i,t,c , zero.q , m1.q , m2.q
    Protected infinity.f=4
    Dim tab.d(4)
    Dim mem1.q(4)
    Dim mem2.q(4)
    zero.q=0
    cp=limit
    fo=infinity
    add=1
    For i=0 To 3
        tab(i)=a
        a+scale
        mem1(i)=0
        mem2(i)=0
    Next

    t=@tab()
    c=@col()
    m1=@mem1()
    m2=@mem2()
    !mov rdx,[p.v_t]
    !VBROADCASTSD ymm8,[p.v_add] ;1  1  1  1
    !VBROADCASTSD ymm7,[p.v_fo] ; 4  4  4  4
    !vmovupd ymm0,[rdx] ;         a1 a2 a3 a4
    !VBROADCASTSD ymm1,[p.v_b] ;  b  b  b  b
    !vmovupd ymm2,ymm0 ; c=a
    !vmovupd ymm3,ymm1 ; d=b
    !VBROADCASTSD ymm9,[p.v_zero];!vpxor ymm9,ymm9,ymm9
   
    !xor rax,rax
    !boucle:
   
    !vmovupd ymm4,ymm0
    !vmovupd ymm5,ymm1
    !vmulpd ymm4,ymm4,ymm4 ; aa = a * a
    !vmulpd ymm5,ymm5,ymm5 ; bb = b * b
   
    !vmovupd ymm6,ymm4
    !vaddpd ymm6,ymm6,ymm5
   
    ;If (aa + bb) > 4.0:Goto fin:EndIf
    !vcmpltpd ymm6,ymm6,ymm7
    !vmovmskpd rcx,ymm6
    !vandpd  ymm6,ymm6,ymm8 ; and 1
    !mov r8,[p.v_m1]
    !mov r9,[p.v_m2]
    !vMOVDQU [r8],ymm6 ; save ymm6
    
    ;!movdqu xmm10,xmm6;[r8]
    !movdqu xmm11,[r8+16]
    !movdqu xmm12,[r9]
    !movdqu xmm13,[r9+16]
    !addpd xmm6,xmm12
    !addpd xmm11,xmm13
    !movdqu [r9],xmm6
    !movdqu [r9+16],xmm11

    !Or rcx,rcx
    !jz fin
   
    ;x1 = 2 * x0 * x1 + x3
    !vmulpd ymm1,ymm1,ymm0 ; b*a
    !vaddpd ymm1,ymm1,ymm1 ; (a*b)*2
    !vaddpd ymm1,ymm1,ymm3 ; (a*b*2)+d
   
    ;x0 = x4 - x5 + c
    !vmovupd ymm0,ymm4 ; a = aa
    !vsubpd ymm0,ymm0,ymm5 ; a = aa - bb
    !vaddpd ymm0,ymm0,ymm2 ;  a = aa - bb + c
   
    !inc rax
    !cmp rax,[p.v_cp]
    !jb boucle
   
    !fin:
    !mov rdx,[p.v_m2]
    !vMOVDQU  ymm9,[rdx]
    !mov rdx,[p.v_c]
    !vMOVDQU [rdx],ymm9
   
    !VZEROALL
   
EndProcedure
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Visualiseur Mandelbrot

Message par Micoute »

Merci manababel, j'ai le pourquoi de la chose, eh bien tant pis, je n'ai plus qu'a changer de carte mère.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre