多线程Python脚本比非线程脚本花费的时间更长 [英] Multithreaded Python script taking longer than non-threaded script

查看:75
本文介绍了多线程Python脚本比非线程脚本花费的时间更长的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:我对多线程非常糟糕,所以我做错事情很可能.

Disclaimer: I'm pretty terrible with multithreading, so it's entirely possible I'm doing something wrong.

我已经用Python编写了一个非常基本的raytracer,我正在寻找可能加快它的速度的方法.多线程似乎是一个选择,所以我决定尝试一下.但是,虽然原始脚本花费了约85秒来处理我的示例场景,但是多线程脚本最终花费了约125秒,这似乎很不直观.

I've written a very basic raytracer in Python, and I was looking for ways to possibly speed it up. Multithreading seemed like an option, so I decided to try it out. However, while the original script took ~85 seconds to process my sample scene, the multithreaded script ends up taking ~125 seconds, which seems pretty unintuitive.

这是原始图片的样子(我不会在这里复制绘图逻辑和内容.如果有人认为需要解决该问题,我会继续将其放回原处):

Here's what the original looks like (I'm not going to copy the drawing logic and stuff in here. If someone thinks that would be needed to figure out the problem, I'll go ahead and put it back in):

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)

这是多线程版本:

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)

有什么明显的地方我做错了吗?还是我认为多线程会加快这样的进程的速度,这是不正确的吗?

Is there something obvious that I'm doing wrong? Or am I incorrect in assuming that multithreading would give a speed boost to a process like this?

推荐答案

我怀疑Python全局解释器锁正在阻止您的代码同时在两个线程中运行.

I suspect the Python Global Interpreter Lock is preventing your code from running in two threads at once.

什么是全局解释器锁(GIL)?

很显然,您想利用多个CPU.您可以在进程而不是线程之间划分光线跟踪吗?

Clearly you want to take advantage of multiple CPUs. Can you split the ray tracing across processes instead of threads?

多线程版本显然可以完成更多的工作",因此我希望它在单个CPU上会更慢.

The multithreaded version obviously does more "work" so I would expect it to be slower on a single CPU.

我也不喜欢子类化Thread,只是用t = Thread(target=myfunc); t.run()

I also dislike subclassing Thread, and just construct a new thread with t = Thread(target=myfunc); t.run()

这篇关于多线程Python脚本比非线程脚本花费的时间更长的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆