j'ai modifié la première version du programme que vous avez posté.
1-le tableau 'BMP' a ete agrandit pour que chaque thread puisse calculer deux lignes de plus.
-ici on attend que tous les threads soient finis, puis on calcule toutes les lignes qui posent problème avec les threads
-en améliorant cette partie, on doit pouvoir supprimer le calcul des deux lignes supplémentaire
Code : Tout sélectionner
Global imax=255,lg=1280,ht=800
Global Dim pal.l(4096)
Global Dim Bmp.l(ht + 2, lg - 1)
Global Dim t.w(ht + 1 , lg + 1)
Global Dim cx.d(lg - 1)
Global Dim cy.d(ht - 1)
Global ndt=CountCPUs(#PB_System_ProcessCPUs )
Global Dim Thread(ndt+1)
Global Event.i,z.d, fx.d, fy.d,zoom.d
Global Dim test(ndt+1)
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()
r.b:g.b:b.b
Dim co.l(65)
;co = Array(&HFF0000, &HFF00FF, &HFF&, &HFFFF&, &H4400&, &HFF0000, &HFF00FF, &HFF&, &HFFFF&, &H4400&, &HFF0000, &HFF00FF, &HFF&, &HFFFF&, &H4400&, &HFF0000, &HFF00FF, &HFF&, &HFFFF&, &H4400&)
For i = 0 To 64: co(i) = Random( $FFFFFF): Next
cl = 8
For j = 0 To 63
For i = 0 To cl - 1
ci = j * cl + i
pal(ci) = ColorBlend(co(j), co(j + 1), i/ cl)
Next
Next
pal(imax) = 0
;For i = 0 To 255: CoRGB pal(i), b, g, r: Line (i * 2, 0)-(i * 2 + 1, 10), RGB(b, g, r), BF: next
EndProcedure
Procedure mandelbrotx1(a.d,b.d)
cp.q=imax
fo.d=4.0
!movsd xmm7,[p.v_fo]
!movsd xmm0,[p.v_a] ; a
!movsd xmm1,[p.v_b] ; b
!movupd xmm2,xmm0 ; c=a
!movupd xmm3,xmm1 ; d=b
!xor rax,rax
!boucle1:
!movupd xmm4,xmm0
!movupd xmm5,xmm1
!mulpd xmm4,xmm4 ; aa = a * a
!mulpd xmm5,xmm5 ; bb = b * b
;If (aa + bb) > 4.0:Goto fin:EndIf
!movupd xmm6,xmm4
!addpd xmm6,xmm5
!VCMPGTPD xmm6,xmm6,xmm7
!movq rdx,xmm6
!cmp rdx,0
!jne fin1
;x1 = 2 * x0 * x1 + x3
!mulpd xmm1,xmm0 ; b*a
!addpd xmm1,xmm1 ; (a*b)*2
!addpd xmm1,xmm3 ; (a*b*2)+d
;x0 = x4 - x5 + c
!movupd xmm0,xmm4 ; a = aa
!subpd xmm0,xmm5 ; a = aa - bb
!addpd xmm0,xmm2 ; a = aa - bb + c
!inc rax
!cmp rax,[p.v_cp]
!jb boucle1
!fin1:
ProcedureReturn ; rax
EndProcedure
Procedure.q mandelbrotx4(a.d,b.d,scale.d,opt=0)
cp.q=imax
fo.d=4
juliacx.d=-0.7
juliacy.d=0.27015
!movsd xmm1,[p.v_scale] ; 00 sc
!movsd xmm2,[p.v_a] ; 00 a0
!addpd xmm2,xmm1 ; a1
!addpd xmm2,xmm1 ; a2
!addpd xmm2,xmm1 ; a3
!movddup xmm0,xmm2 ; a3 a3
!subpd xmm0,xmm1 ; a3 a2
!VINSERTF128 ymm0,ymm0,xmm0,1 ; a3 a2 a3 a2
!subpd xmm0,xmm1 ; a1
!movddup xmm0,xmm0 ; a3 a2 a1 a1
!subpd xmm0,xmm1 ; a3 a2 a1 a0
!mov rax,1
!movq xmm8,rax
!VPBROADCASTQ ymm8,xmm8
!VBROADCASTSD ymm7,[p.v_fo] ; 4 4 4 4
!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
!cmp rax,[p.v_opt]
!je NotJulia
!VBROADCASTSD ymm2,[p.v_juliacx]
!VBROADCASTSD ymm3,[p.v_juliacy]
!NotJulia:
!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 ; zx*zy
!vaddpd ymm1,ymm1,ymm1 ; (zx*zy)*2
!vaddpd ymm1,ymm1,ymm3 ; (zx*zy*2)+cy
;x0 = x4 - x5 + c
!vmovupd ymm0,ymm4 ; a = aa
!vsubpd ymm0,ymm0,ymm5 ; a = aa - bb
!vaddpd ymm0,ymm0,ymm2 ; a = zx - zy + cx
!inc rax
!cmp rax,[p.v_cp]
!jb boucle
!fin:
;00c1 00c2 00c3 00c4
!pxor xmm2,xmm2
!Vpshufd ymm9,ymm9,216 ; 0000 c1c2 0000 c3c4
!VEXTRACTI128 xmm0,ymm9,1 ; 0000 c1c2
!packusdw xmm9,xmm2 ; 32 -> 16 bits
!packusdw xmm0,xmm2
!psllq xmm0,32
!por xmm9,xmm0 ; c1c2c3c4 4*16
!movq rax,xmm9
!VZEROALL
ProcedureReturn
EndProcedure
Procedure fractale(num)
Protected i,j,jdeb,jfin ,px,py , scale.d , var.q
jdeb=ht/ndt*num
jfin=ht/ndt*(num+1)+2
test(num)=jfin
If jfin>=ht : ProcedureReturn : EndIf
For i = 0 To lg - 1 : cx(i) = zoom * ((2 * i) / lg -1) * lg / ht + fx: Next
For j = jdeb To jfin-1: cy(j) = zoom * ((2 * j) / ht -1) + fy: Next
scale = cx(2) - cx(0)
dd=2
For jj = jdeb/dd To jfin/dd:j=jj*dd
For ii = 0 To lg/dd - 1 Step 4:i=ii*dd
var = mandelbrotx4((cx(i)), (cy(j)),scale)
t(j,i+0) = ( var >> 00 ) & 255
t(j,i+2) = ( var >> 16 ) & 255
t(j,i+4) = ( var >> 32 ) & 255
t(j,i+6) = ( var >> 48 ) & 255
Next
Next
While dd > 1
d = dd / 2: c1 = 0: c2 = 0: c3 = 0
For jj = jdeb/dd+2 To jfin/dd :j=jj*dd-d
For ii = 2 To lg/dd - 1 :i=ii*dd-d
pa = t(j - d,i - d)
pb = t(j + d,i - d)
pc = t( j + d,i + d)
pd = t(j - d,i + d)
If pa = pb And pa = pc And pa = pd
pe = pa: c1 = c1 + 1
Else
pe = mandelbrotx1((cx(i)), (cy(j)))
EndIf
pf = t( j,i - dd)
pg = t(j - dd,i)
t(j,i) = pe
If pe = pc And pe = pf And pe = pd
t( j,i + d) = pe: c2 = c2 + 1
Else
t(j,i + d) = mandelbrotx1(cx(i + d), cy(j))
EndIf
If pe = pc And pe = pg And pe = pb
t(j + d,i) = pe: c3 = c3 + 1
Else
t(j + d,i) = mandelbrotx1((cx(i)), (cy(j + d)))
EndIf
Next
Next
dd = dd / 2
;Debug lg * ht, c1; c2; c3
Wend
For j=jdeb To jfin-1
For i=0 To lg-1
bmp(j+1,i)=pal(t(j,i))
Next
Next
EndProcedure
Procedure fractale_test()
For k=0 To ndt-1
jdeb=test(k)
jfin=jdeb
If jfin>=ht : ProcedureReturn : EndIf
;For i = 0 To lg - 1 : cx(i) = zoom * ((2 * i) / lg -1) * lg / ht + fx: Next
;For j = jdeb To jfin-1: cy(j) = zoom * ((2 * j) / ht -1) + fy: Next
dd=2
;While dd > 1
d = dd / 2: c1 = 0: c2 = 0: c3 = 0
j=jfin
;For jj = jdeb/dd+2 To jfin/dd :j=jj*dd-d
For ii = 2 To lg/dd - 1 :i=ii*dd-d
pa = t(j - 1,i - 1)
pb = t(j + 1,i - 1)
pc = t( j + 1,i + 1)
pd = t(j - 1,i + 1)
If pa = pb And pa = pc And pa = pd
pe = pa: c1 = c1 + 1
Else
pe = mandelbrotx1((cx(i)), (cy(j)))
EndIf
pf = t( j,i - dd)
pg = t(j - dd,i)
t(j,i) = pe
If pe = pc And pe = pf And pe = pd
t( j,i + 1) = pe: c2 = c2 + 1
Else
t(j,i + 1) = mandelbrotx1(cx(i + 1), cy(j))
EndIf
If pe = pc And pe = pg And pe = pb
t(j + 1,i) = pe: c3 = c3 + 1
Else
t(j + 1,i) = mandelbrotx1((cx(i)), (cy(j + 1)))
EndIf
Next
;Next
dd = dd / 2
;Debug lg * ht, c1; c2; c3
;Wend
;For j=jdeb To jfin-1
For i=0 To lg-1
bmp(j+1,i)=pal(t(j,i))
Next
;Next
Next
EndProcedure
OpenWindow(0, 0, 0, lg, ht, "Mandelbrot", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, lg, ht, #PB_Canvas_ClipMouse | #PB_Canvas_Keyboard)
CreateImage(0, lg, ht, 32)
InitPalette()
zoom = 1:dx=1
Repeat
Event = WindowEvent()
If Event = #PB_Event_Gadget
X = GetGadgetAttribute(0, #PB_Canvas_MouseX)
Y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
z = GetGadgetAttribute(0, #PB_Canvas_WheelDelta)
b = GetGadgetAttribute(0, #PB_Canvas_Buttons)
If b:dx=x-ax:dy=y-ay:Else:dx=0:dy=0:EndIf
ax=x:ay=y
EndIf
If z Or dx Or dy
zoom=zoom*(1-0.1*z)
fx-dx*zoom/ht
fy+dy*zoom/ht
;ti=ElapsedMilliseconds()
For i=0 To ndt-1:Thread(i)=CreateThread(@fractale(),i):Next
For i=0 To ndt-1:If Thread(i) : WaitThread(thread(i)):EndIf:Next
fractale_test()
StartDrawing(ImageOutput(0))
CopyMemory(@bmp(0,0),DrawingBuffer(),lg*ht*4)
StopDrawing()
;ti=ElapsedMilliseconds()-ti
StartDrawing(CanvasOutput(0))
DrawImage(ImageID(0),0,0,lg,ht)
DrawingMode(#PB_2DDrawing_Transparent )
DrawText(10,10,"Z:" + zoom+ " X:"+x +" Y:"+y)
;DrawText(10,25,Str(ti))
StopDrawing()
EndIf
Until Event = #PB_Event_CloseWindow