Thank you for the replies everyone!
If you're interested, here is the dual core version:
https://github.com/hwiguna/HariFun_202_ ... ualCore.py
It works, but it is only marginally faster than the single core version:
https://github.com/hwiguna/HariFun_202_ ... rotQuik.py
I tried to distribute the mandelbrot calculation equally between the two cores by going though the X axis in steps of 2.
All Y for X is calculated by the thread, and all Y for X+1 is calculated by main thread.
Functions of interest are:
Loop() where I call DrawMandelbrotX() and then wait for user input.
DrawMandelbrotX() where I spin a thread to compute all Y pixels for column X, and also compute all Y pixels for column X+1 then loop to X+2
mandelbrotThreadX() is basically the same calculation as in DrawMandelbrotX() but stores the pixel results in an array of booleans.
When done I set a global variable resultsReady to True.
Back in DrawMandelbrotX() I wait for resultsReady to become true, then plot the results pixel array on the actual screen.
Do you see how we could improve this code for better multi core performance? Thanks!!!
Code: Select all
def mandelbrotThreadX(x):
global MAX_ITER
global WIDTH, HEIGHT, realStart, realEnd, imStart, imEnd
global results, resultsReady
#print("Thread Begin x=",x)
xx = realStart + (x / WIDTH) * (realEnd - realStart)
# for y in range(HEIGHT):
# results[y]=False
for y in range(HEIGHT):
yy = imStart + (y / HEIGHT) * (imEnd - imStart)
c = complex(xx, yy) # Convert pixel coordinate to complex number
m = mandelbrot(c) # Compute the number of iterations
color = 1 - int(m/MAX_ITER)
results[y] = color>0
resultsReady = True
#print("Thread Done x", x)
_thread.exit() # when done, commit suicide so we could be re-incarnated for next X.
def DrawMandelbrotX():
global oled, brotFB, cursorFB, isHiRez, nextRefresh, MAX_ITER
global results, resultsReady
print("DRAWING:", realStart, realEnd, imStart, imEnd)
stopWatch = time.ticks_ms()
RE_START = realStart
RE_END = realEnd
IM_START = imStart
IM_END = imEnd
brotFB.fill(0)
for x in range(0, WIDTH,2): # We're drawing two columns at a time. One by the thread, the other by main.
resultsReady=False # Will be set by thread to True when it's done computing column.
_thread.start_new_thread(mandelbrotThreadX,(x,))
x1 = x+1
#print("Main begin x1=",x1)
xx = RE_START + (x1 / WIDTH) * (RE_END - RE_START)
for y in range(0, HEIGHT, 1):
yy = IM_START + (y / HEIGHT) * (IM_END - IM_START)
c = complex(xx, yy) # Convert pixel coordinate to complex number
m = mandelbrot(c) # Compute the number of iterations
color = 1 - int(m/MAX_ITER)
brotFB.pixel(x1,y, 1 if color>0 else 0) # Plot the point
#print("Main End x1=",x1)
#stopwatchStart = time.ticks_ms()
while not resultsReady:
pass
#print("waited ", time.ticks_ms()-stopwatchStart, "ms")
# Plot the X column computed by the thread
for y in range(HEIGHT):
brotFB.pixel(x,y, 1 if results[y] else 0)
if x % 6 == 0: # No need to refresh everytime we go through X loop.
oled.blit(brotFB,0,0)
oled.show()
oled.blit(brotFB,0,0)
oled.show()