多线程Python脚本比非线程脚本花费更长时间

cto*_*eal 3 python multithreading

免责声明:我对多线程非常糟糕,所以我完全有可能做错了.

我在Python中编写了一个非常基本的光线跟踪器,我一直在寻找可能加速它的方法.多线程似乎是一种选择,所以我决定尝试一下.但是,虽然原始脚本需要大约85秒来处理我的示例场景,但多线程脚本最终需要大约125秒,这看起来非常不直观.

这是原始的样子(我不会复制绘图逻辑和东西.如果有人认为需要找出问题,我会继续把它放回去):

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)
Run Code Online (Sandbox Code Playgroud)

这是多线程版本:

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)
Run Code Online (Sandbox Code Playgroud)

有什么明显的东西我做错了吗?或者我错误地假设多线程会对这样的进程提速?

Joe*_*erg 8

我怀疑Python Global Interpreter Lock会阻止您的代码同时在两个线程中运行.

什么是全球翻译锁(GIL)?

显然,您希望利用多个CPU.你能跨进程而不是线程分割光线跟踪吗?

多线程版本显然做了更多"工作",所以我希望它在单个CPU上更慢.

我也不喜欢子类化Thread,只是构造一个新的线程t = Thread(target=myfunc); t.run()