【问题标题】:How can I best improve the execution time of a bicubic interpolation algorithm?如何最好地改善双三次插值算法的执行时间?
【发布时间】:2011-06-17 08:53:50
【问题描述】:

我正在英特尔上用 C++ 开发一些图像处理软件,它必须一遍又一遍地在小(大约 1kpx)图像上运行双三次插值算法。这需要很多时间,我的目标是加快速度。我现在拥有的是一个基于文献的基本实现,一个稍微改进的(关于速度)版本,它不进行矩阵乘法,而是对插值多项式和最后一个固定的部分使用预先计算的公式矩阵乘法代码的点版本(实际上工作得更慢)。我也有一个具有优化实现的外部库,但对于我的需求来说它仍然太慢。我接下来考虑的是:

  • 在浮点和定点版本上使用 MMX/SSE 流处理进行矢量化
  • 使用卷积在傅里叶域中进行插值
  • 使用 OpenCL 或类似工具将工作转移到 GPU 上

这些方法中的哪一种可以产生最大的性能提升?你能推荐另一个吗?谢谢。

【问题讨论】:

  • 我们说的有多慢?慢是因为您多次执行相对较快的操作,还是因为它比您预期的慢很多?
  • 我想它比较快,但我需要做很多次。外部库大约需要 27us(使用 SSE),我最好的实现大约需要 50us。
  • 如果你使用GPU,你如何处理算法的输出,你是否需要回到主内存,这本身可能是一个瓶颈?
  • 你指的这个“外部库”是什么? 1k px 图像也是 100x10 还是 1000x1000?
  • 我使用的库是OpenCV。至于图像的大小,我的意思是总共 1000 像素。它们通常是正方形的,大小为 32x32。

标签: c++ performance image-processing interpolation bicubic


【解决方案1】:

我认为 GPU 是要走的路。对于这类硬件来说,这可能是最自然的任务。我会先研究CUDAOpenCL。简单的 DirectX/OpenGL 像素/片段着色器等较旧的技术也应该可以正常工作。

我找到了一些链接,也许它们可以帮助你:

【讨论】:

    【解决方案2】:

    还有Intel IPP libraries,它在内部使用 SIMD 来加快处理速度。英特尔 IPP 还使用 OpenMP,如果配置,您可以获得相对简单的多处理的好处。

    这些库确实支持双三次插值并且是付费软件(您购买了开发许可证,但重新分发是免费的)。

    【讨论】:

    • +1:您现在在购买英特尔 ICC 编译器时获得 IPP 许可(并且没有运行时许可问题)。单独的 ICC 应该比 gcc 或 Visual Studio 有一些性能改进,在编写自定义 SIMD 代码之前,IPP 肯定是首先尝试的。
    • @Paul R,感谢您的精彩提示,我将认真研究此编译器。
    • @ChrisO 我看到 IPP 支持三次插值,但不支持双三次。它们被认为是相同的吗?
    • @JoaoMilasch 是的,我相信“bicubic”和“cubic”是同一个概念,如果你看一下ippiman.pdf中的图B-2,你可以看到三次多项式在二维。
    【解决方案3】:

    走 GPU 路线时要小心。如果你的卷积核太快,你最终会受到 IO 限制。除非您同时实现两者,否则您将无法确定哪个最快。

    GPU Gems 2 有一个关于 Fast Third-Order Texture Filtering 的章节,这应该是您的 GPU 解决方案的一个很好的起点。

    Intel Threading Building Blocks 和 SSE 指令的组合将是一个不错的 CPU 解决方案。

    【讨论】:

      【解决方案4】:

      不是双三次的答案,但也许是另一种选择:
      如果我理解你的话,你有 32 x 32 xy、1024 x 768 的图像,并且想要插值 image[xy]
      只是舍入 xy,image[ int( xy )],会太粗糙。
      但是等等——你可以制作一个 2k x 1.5k 的平滑双图像,一次,然后拍摄
      image2[ int( 2*xy )]:颗粒更少,速度非常快。或者类似地,
      image4[ int( 4*xy )] 在平滑的 4k x 3k 图像中。
      效果如何取决于...

      【讨论】:

      • 其实是反过来的;我有一个 1024x768 的图像,我想根据“图像”中非均匀分布的数据点创建一个插值的 32x32 xy。
      • 是的,图像[xy] 是图像的 32x32。考虑 1d, 32 个值在 x0 .. x31 从 1k 点:如果你想从一个图像中插入许多不同的 xy(你的情况是这样吗?),将图像平滑放大一次,到 2k 或 4k,然后取 32 xy 的值四舍五入为整数。它们以一半/四分之一像素对原始图像进行采样,速度很快。
      猜你喜欢
      • 2015-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      相关资源
      最近更新 更多