V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
fffflyfish
V2EX  ›  Python

关于 python 并行计算的问题

  •  
  •   fffflyfish ·
    FormatFish · 2016-11-25 20:46:16 +08:00 · 4023 次点击
    这是一个创建于 2945 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家好,这两天遇到一个运算速度的问题,就是我的程序是关于图像处理的,有的函数是要通过把一张图片的每个像素点扫描,然后计算一些值,比如这样一个场景:有一张画布,上面有 3 个元素,我现在要计算每个空白位置的像素点与这三个元素之间的最短距离,这样如果画布面积太大,就会导致算法运行时间过长,实测的话 800x600 的画布,将这个函数循环迭代 600 次,就得耗时 10 个小时+,所以我想通过并行计算来试试,因为目前的服务器配置是 8 核 E5 2650V3 的,感觉自己的程序只用到了一个核。但是关于这方面的知识我不是很懂,所以请教一下各位,谢谢!

    第 1 条附言  ·  2016-11-25 22:20:20 +08:00

    还是V站的前辈见识比较广,我要查一下这些技术,消化一下。。。。谢谢各位

    27 条回复    2016-12-02 20:43:25 +08:00
    xujunfu
        1
    xujunfu  
       2016-11-25 20:47:45 +08:00 via iPhone
    cuda mpi openmp
    justou
        2
    justou  
       2016-11-25 21:00:32 +08:00
    这种问题用 GPU 算比 CPU 并行高效得多
    比如 opengl 还有 1L 提到的 cuda, 都有 python 接口
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       2016-11-25 21:17:42 +08:00
    奇怪! 为何要循环做, 计算这个问题应该有数学方法直接解决的。。
    sagaxu
        4
    sagaxu  
       2016-11-25 21:23:05 +08:00 via Android
    自己搜索 python gil
    fffflyfish
        5
    fffflyfish  
    OP
       2016-11-25 21:25:34 +08:00
    @justou 用的是阿里云服务器,貌似没看见有 GPU ,我想的是把一张图片切割然后分配到各个线程里去计算, cuda 的话感觉只是对矩阵运算的时候优势会大一点
    fffflyfish
        6
    fffflyfish  
    OP
       2016-11-25 21:33:24 +08:00
    @zhuangzhuang1988 我这个问题就是来自一篇论文的函数,按照文章的说法,就是逐个像素的计算,我想的优化方法就是类似卷积神经网络里的汇聚层一样,但是现在是想先利用下当前服务器 8 核这个优势
    fffflyfish
        7
    fffflyfish  
    OP
       2016-11-25 21:33:57 +08:00
    @sagaxu 看起来不错,谢谢
    justou
        8
    justou  
       2016-11-25 21:40:03 +08:00
    哦, 我以为就用自己 PC 算...
    上面打错了, 想写 opencl, 虽然 opengl 的计算着色器也能完成
    图片就是一个矩阵, 放到显卡上, 每个计算单元计算一个像素跟三个元素的距离, 最后得到最短距离跟对应像素, 不需要任何循环
    zhuangzhuang1988
        9
    zhuangzhuang1988  
       2016-11-25 21:49:22 +08:00
    如果没有 gpu
    用 tbb 吧。。
    这货参数配置得好,能让你的服务器爽死。。
    fffflyfish
        10
    fffflyfish  
    OP
       2016-11-25 22:19:38 +08:00
    @zhuangzhuang1988 看起来不错,我研究下,谢谢!


    @justou 嗯,我试试我本地的电脑可不可以,听起来有点厉害啊,我研究下吧,谢谢啦
    stamaimer
        11
    stamaimer  
       2016-11-25 23:47:01 +08:00 via iPhone
    我感觉你这个问题,写个多进程程序就能解决。
    lll9p
        12
    lll9p  
       2016-11-26 00:08:59 +08:00 via Android
    想办法向量化啊, py 的循环多慢啊。。
    tigerstudent
        13
    tigerstudent  
       2016-11-26 00:12:54 +08:00
    如果只是简单地改成多进程,也不过是将 10 小时缩短到一两个小时吧,效果并不太大。
    henices
        14
    henices  
       2016-11-26 11:45:21 +08:00 via Android
    pool.map
    stamaimer
        15
    stamaimer  
       2016-11-26 12:01:10 +08:00 via iPhone
    @tigerstudent 你测试过了?
    fffflyfish
        16
    fffflyfish  
    OP
       2016-11-26 12:01:43 +08:00
    @lll9p
    @tigerstudent 嗯,还是要在算法方面想办法,图像逐像素处理确实不是一个长久的方法
    Jblue
        17
    Jblue  
       2016-11-26 20:16:54 +08:00
    将三个图片等分,然后并行跑如何呢, pillow 优于 pil 。
    fffflyfish
        18
    fffflyfish  
    OP
       2016-11-26 22:20:49 +08:00
    @Jblue 哈我用的就是 pillow ,这个方法我也想过,但是因为要求元素之间最短距离,分开的话就不知道怎么处理了,毕竟元素的位置分散在画布上
    wjidea
        19
    wjidea  
       2016-11-27 11:19:49 +08:00
    multiprocessing
    congeec
        20
    congeec  
       2016-11-27 13:41:33 +08:00 via iPhone
    @fffflyfish 你用 pillow-simd 了?
    fffflyfish
        21
    fffflyfish  
    OP
       2016-11-27 20:09:22 +08:00
    @congeec 没,就是普通的 pillow
    fffflyfish
        23
    fffflyfish  
    OP
       2016-11-28 00:24:24 +08:00 via iPad
    @linhua 哇,简直不能更 cool ,谢谢!
    congeec
        24
    congeec  
       2016-11-29 03:46:09 +08:00 via iPhone
    @fffflyfish 如果底层还是 pillow ,用 cpu 算,还是建议试试 simd 版本
    fffflyfish
        25
    fffflyfish  
    OP
       2016-11-29 14:03:53 +08:00
    @congeec 嗯,之前查过了,这个 simd 版本对 cpu 并行有过优化,可以可以,谢谢啦
    justou
        26
    justou  
       2016-12-02 17:11:58 +08:00
    我实际操作了下你这个问题, 把问题简化成了: 计算图片上到若干像素距离最短的位置, 效率并不算太差啊
    到 3, 10, 30, 81 个像素最短距离的计算时间分别是: 160 ms, 460 ms, 1.34 s, 3.55 s, 时间线性递增, 还没用 opencl 试
    (注: 当点数过多的时候最短距离的位置不一定只有一个)

    https://gist.github.com/justou/b64a0b73fe198a2b6cdb1c72b3459ad8
    fffflyfish
        27
    fffflyfish  
    OP
       2016-12-02 20:43:25 +08:00
    @justou 好优雅的代码!不过你现在把画布上的一个元素简化成了一个像素点(就是你代码里随机产生的位置),但是对于我现在做的东西来说,这个元素是不能简单的以一个像素点来看待,必须是一个 bounding box , 比如说一张广告,上面的标题元素,比如字号为 60 ,那么它占的像素面积就是一个 axb 大小的矩形框,如果求图片空白区域的每个像素点(无元素的地方)到它的距离,这就有点麻烦了,因为这个元素也是有很多像素点的, 我现在用的方法是 python 里的 scipy 的 distance_transform_edt 函数,链接: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.ndimage.morphology.distance_transform_edt.html


    这是目前我找到的最好的解决方法,但是计算时间还是不理想,这两天在看 multiprocess 的东西,应该会有用。

    非常感谢您能腾出时间来考虑我的问题,谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 14:01 · PVG 22:01 · LAX 06:01 · JFK 09:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.