如何加速Python代码在强大的机器上运行?

时间:2014-06-19 12:10:13

标签: python performance numpy cuda gpu

我已经完成了使用增强分类器编写多类分类算法。其中一个主要计算包括加权最小二乘回归。 我使用的主要库包括:

  • statsmodels(用于回归)
  • numpy(几乎无处不在)
  • scikit-image(用于提取图像的HoG特征)

我使用Anaconda的Spyder在Python中开发了算法。

我现在需要使用该算法来开始训练分类模型。因此,我将向此算法传递大约7000-10000个图像,每个图像大约50x100,全部为灰度级。

现在我被告知有一台功能强大的机器可以加速训练过程。他们问我“我在使用GPU吗?”还有一些问题。

说实话,我没有CUDA / GPU等经验。我只听说过它们。我没有考虑任何这样的事情来开发我的代码。事实上,我有一种(无知的)印象,一台好的机器会比一个平庸的机器更快地自动运行我的代码,而不需要对它做任何事情。 (除了显然在循环,O(n)等方面有效地编写常规代码)。

我的代码是否仍然可以通过在高性能计算机上加速来加速?或者我是否需要修改它以使用并行处理机器?

2 个答案:

答案 0 :(得分:7)

评论和Moj的回答提供了很多好的建议。我在使用python进行信号/图像处理方面有一些经验,并且已经反复撞击性能墙,我只是想分享一些关于使事情变得更快的想法。也许这些有助于通过慢速算法找出可能的解决方案。

花费的时间在哪里?

让我们假设你有一个很好的算法,这个算法太慢了。第一步是对其进行分析以查看花费的时间。有时花时间以愚蠢的方式做琐碎的事情。它可能在您自己的代码中,也可能在库代码中。例如,如果要运行具有较大内核的2D高斯滤波器,则直接卷积非常慢,甚至FFT可能很慢。用计算上廉价的连续滑动平均值逼近滤波器可能会在某些情况下将速度提高10或100倍,并得出足够接近的结果。

如果在某些模块/库代码中花费了大量时间,则应检查算法是否只是一种慢速算法,或者库是否存在某些缓慢的问题。 Python是一种很棒的编程语言,但对于纯数字运算操作来说,这并不好,这意味着大多数优秀的库都有一些二进制库正在进行繁重的工作。另一方面,如果你能找到合适的库,那么在信号/图像处理中使用python的代价往往可以忽略不计。因此,用C语言重写整个程序通常没有多大帮助。

即使在C语言中编写一个好的算法并不总是微不足道的,有时候性能可能会有很大差异,具体取决于CPU缓存等。如果数据在CPU缓存中,则可以非常快地获取数据,如果不是,那么算法要慢得多。这可能会根据数据大小将非线性步骤引入处理时间。 (大多数人从虚拟内存交换中了解到这一点,它更加明显。)由于这个原因,解决100个问题的问题可能比10 000个问题的1个问题更快。

要检查的一件事是计算中使用的精度。在某些情况下,float32和float64一样好但速度要快得多。在许多情况下没有区别。

<强>多线程

Python - 我提到了吗? - 是一种很棒的编程语言,但它的一个缺点是它的基本形式是运行一个线程。因此,无论您的系统中有多少核心,挂钟时间总是相同的。结果是其中一个核心处于100%,而其他核心则花费时间闲置。使事物平行并具有多个线程可以将您的性能提高一倍,例如4核机器中的3倍。

如果您可以将问题分成小的独立部分,通常是个好主意。它有助于解决许多性能瓶颈问题。

并且不要指望技术来拯救。如果代码不是并行编写的,那么机器很难使其并行。

<强>的GPU

你的机器可能有一个很棒的GPU,可能有1536个需要耗费数量的核心,可以随时处理你扔掉的所有东西。坏消息是制作GPU代码与编写CPU代码有点不同。有一些稍微通用的API(CUDA,OpenCL),但是如果你不习惯为GPU编写并行代码,那么应该准备一个陡峭的学习曲线。另一方面,很可能有人已经编写了你需要的库,然后你只需要勾选它。

使用GPU时,绝对数字处理能力令人印象深刻,几乎令人恐惧。我们可以谈论3个TFLOPS(每秒3 x 10 ^ 12个单精度浮点运算)。问题在于如何将数据传输到GPU核心,因为内存带宽将成为限制因素。这意味着即使在许多情况下使用GPU是一个好主意,但在很多情况下都没有增益。

通常,如果您在图像上执行大量本地操作,则操作很容易并行,并且它们非常适合GPU。如果您正在进行全球运营,情况会更复杂一些。 FFT需要来自整个图像的信息,因此标准算法不适用于GPU。 (有基于GPU的FFT算法,它们有时会使事情变得更快。)

另外,请注意,让您的算法在GPU上运行会将您绑定到该GPU。跨越操作系统或机器的代码的可移植性受到影响。

购买一些表现

另外,需要考虑的一件重要事情是,您需要运行一次算法,偶尔或实时运行算法。有时,解决方案就像从较大的计算机上购买时间一样简单。每小时一两美元,您可以从拥有大量资源的相当快的机器上购买时间。它比你想象的更简单,也更便宜。此外,GPU容量可以以类似的价格轻松购买。

某些云服务的一个可能略微宣传不足的属性是,在某些情况下,与物理机相比,虚拟机的IO速度非常好。不同之处在于没有旋转盘片,每个数据搜索的平均罚分为半转。这对于数据密集型应用程序可能很重要,特别是如果您使用大量文件并以非线性方式访问它们。

答案 1 :(得分:4)

我担心你只能在功能强大的计算机上运行它来加速你的程序。我回来时遇到了这个问题。我首先使用python(非常慢),然后转移到C(慢)然后不得不使用其他技巧和技巧。例如,有时可以应用一些降维来加速事物,同时获得合理的准确结果,或者如您提到的那样使用多处理技术。

由于您正在处理图像处理问题,因此您需要进行大量的矩阵运算,GPU肯定会有很大的帮助。在python中有一些很好的和活跃的cuda包装器,你可以很容易地使用,因为不了解太多的CUDA。我尝试了Theano,pycuda和scikit-cuda(从那以后应该有更多)。