Page 1 sur 2

Visualiseur Mandelbrot

Publié : mer. 21/oct./2020 23:09
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)

Re: Visualiseur Mandelbrot

Publié : jeu. 22/oct./2020 20:06
par Ar-S
C'est top.

Re: Visualiseur Mandelbrot

Publié : jeu. 22/oct./2020 20:41
par SPH
Super rapide :idea:

Re: Visualiseur Mandelbrot

Publié : ven. 23/oct./2020 10:55
par Micoute
Curieusement, à la ligne 47, j'ai [ERREUR] Instruction illégale. (exécution de données binaires?)

Re: Visualiseur Mandelbrot

Publié : ven. 23/oct./2020 15:40
par manababel
Tres bien .

attention , le programme bug si on change de resolution.

Re: Visualiseur Mandelbrot

Publié : ven. 23/oct./2020 16:14
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 ?

Re: Visualiseur Mandelbrot

Publié : ven. 23/oct./2020 16:23
par manababel
les résolutions "bâtards"

exemple 1281x723

Re: Visualiseur Mandelbrot

Publié : ven. 23/oct./2020 17:33
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







@++

Re: Visualiseur Mandelbrot

Publié : sam. 24/oct./2020 16:57
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.

Re: Visualiseur Mandelbrot

Publié : sam. 24/oct./2020 19:22
par venom
Micoute tu as la même erreur que moi en 32 bits ? Quel est ta résolution d'écran ?






@++

Re: Visualiseur Mandelbrot

Publié : sam. 24/oct./2020 20:02
par GallyHC
Bonjour,

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

Cordialement,
GallyHC

Re: Visualiseur Mandelbrot

Publié : sam. 24/oct./2020 20:31
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







@++

Re: Visualiseur Mandelbrot

Publié : dim. 25/oct./2020 17:29
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.

Re: Visualiseur Mandelbrot

Publié : lun. 26/oct./2020 15:16
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

Re: Visualiseur Mandelbrot

Publié : mar. 27/oct./2020 15:38
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.