A multi-threaded Python script takes more than a non-threaded script

Disclaimer: I am very scared of multithreaded, so it is quite possible that I am doing something wrong.

I wrote a very simple raytracer in Python, and I was looking for ways to speed it up. Multithreading seemed like an option, so I decided to try it. However, although the original script took about 85 seconds to process the sample scene, the multithreaded script ends up taking ~ 125 seconds, which seems rather unintuitive.

Here's what the original looks like (I'm not going to copy the drawing logic and stuff here. If someone thinks what it takes to figure out the problem, I'll come back and get it back):

def getPixelColor(x, y, scene):
    <some raytracing code>

def draw(outputFile, scene):
    <some file handling code>
    for y in range(scene.getHeight()):
        for x in range(scene.getWidth()):
            pixelColor = getPixelColor(x, y, scene)
            <write pixelColor to image file>

if __name__ == "__main__":
    scene = readScene()
    draw(scene)

And here is the multithreaded version:

import threading
import Queue

q = Queue.Queue()
pixelDict = dict()

class DrawThread(threading.Thread):
    def __init__(self, scene):
        self.scene = scene
        threading.Thread.__init__(self)

    def run(self):
        while True:
        try:
            n, x, y = q.get_nowait()
        except Queue.Empty:
            break
        pixelDict[n] = getPixelColor(x, y, self.scene)
        q.task_done()

    def getPixelColor(x, y, scene):
        <some raytracing code>

def draw(outputFile, scene):
    <some file handling code>
    n = 0
    work_threads = 4
    for y in range(scene.getHeight()):
        for x in range(scene.getWidth()):
            q.put_nowait((n, x, y))
            n += 1
    for i in range(work_threads):
        t = DrawThread(scene)
        t.start()
    q.join()
    for i in range(n)
        pixelColor = pixelDict[i]
        <write pixelColor to image file>

if __name__ == "__main__":
    scene = readScene()
    draw(scene)

- , ? , , ?

+3
3

, Python Global Interpreter Lock .

(GIL)?

, . ?

, , "", , CPU.

Thread, t = Thread(target=myfunc); t.run()

+8

, Python , GIL .

, . Python 2 , C ++ .

, Python, .

+2

, ( , ). -, , Global Interpreter Lock, , .

-, , ( - , ). , , ? , . , , , , , , .

+2

Source: https://habr.com/ru/post/1681005/


All Articles