适用于.NET的最快PNG解码器

sbo*_*sse 27 c# performance png decode decoding

在将结果发送到Web客户端之前,我们的Web服务器需要将大量图像组合在一起.此过程对性能至关重要,因为服务器每小时可以接收数千个请求.

现在我们的解决方案从HD加载PNG文件(每个大约1MB)并将它们发送到视频卡,以便在GPU上完成合成.我们首先尝试使用XNA API公开的PNG解码器加载我们的图像.我们看到表现不太好.

要了解问题是从HD加载还是解码PNG,我们通过将文件加载到内存流中,然后将该内存流发送到.NET PNG解码器来修改它.使用XNA或使用System.Windows.Media.Imaging.PngBitmapDecoder类的性能差异并不重要.我们大致获得相同的性能水平.

我们的基准测试显示以下性能结果:

  • 从磁盘加载图像:37.76ms 1%
  • 解码PNG:2816.97ms 77%
  • 在视频硬件上加载图像:196.67ms 5%
  • 成分:87.80ms 2%
  • 从视频硬件获取作品结果:166.21ms 5%
  • 编码为PNG:318.13ms 9%
  • 存储到磁盘:3.96ms 0%
  • 清理:53.00ms 1%

总计:3680.50ms 100%

从这些结果中我们看到最慢的部分是在解码PNG时.

所以我们想知道是否会有我们可以使用的PNG解码器,这将允许我们减少PNG解码时间.我们还考虑将图像保持在硬盘上不压缩,但是每个图像的大小为10MB而不是1MB,并且由于硬盘上存储了数万个这样的图像,因此无法存储它们.压缩.

编辑:更有用的信息:

  • 基准测试模拟加载20个PNG图像并将它们合成在一起.这大致对应于我们将在生产环境中获得的请求类型.
  • 组合物中使用的每个图像的尺寸为1600×1600.
  • 该解决方案将涉及多达10个负载平衡服务器,就像我们在这里讨论的那样.因此额外的软件开发工作可能值得节省硬件成本.
  • 我们正在考虑缓存解码的源图像,但每种组合很可能使用完全不同的源图像完成,因此缓存未命中率高,性能提升低.
  • 基准测试是用一个糟糕的视频卡完成的,所以我们可以期待使用体面的视频卡将PNG解码更加成为性能瓶颈.

Ani*_*Ani 6

还有另一种选择.也就是说,您编写自己的基于GPU的PNG解码器.您可以使用OpenCL来相当有效地执行此操作(并使用OpenGL执行您的组合,OpenGL可以与OpenCL共享资源).还可以交错传输和解码以获得最大吞吐量.如果这是您可以/想要追求的路线,我可以提供更多信息.

以下是与基于GPU的DEFLATE(和INFLATE)相关的一些资源.

  1. 使用GPU加速无损压缩
  2. 在Google代码上使用CUDA进行gpu-block-compression.
  3. GPU上的浮点数据压缩速度为75 Gb/s - 请注意,这不是使用INFLATE/DEFLATE,而是一种新的并行压缩/解压缩方案,它更适合GPU.

希望这可以帮助!


EKS*_*EKS 4

您是否尝试过以下两件事。

1)
多线程,有多种方法可以做到这一点,但其中一种是“all in”方法。对于整个过程来说,基本上完全生成 X 数量的线程。

2)
也许考虑让XX线程完成所有CPU工作,然后将其提供给GPU线程。

对于新用户来说,您的问题非常明确,但是有关 senario 的一些信息可能有用吗?我们是在谈论批量作业还是实时服务图片?10k张图片有变化吗?

硬件资源
您还应该考虑您拥有哪些硬件资源。通常,最便宜的两个因素是 CPU 能力和磁盘空间,因此,如果您只有 10k 很少变化的图片,那么将它们全部转换为更快处理的格式可能是最佳选择。

多线程琐事
进行多线程处理时要考虑的另一件事是,通常明智地使线程处于 BellowNormal 优先级。因此,您不会使整个系统“滞后”。您必须对要使用的线程数量进行一些试验,如果您幸运的话,您可以在 CORE 上获得接近 100% 的速度增益,但这在很大程度上取决于您运行的硬件和代码。

我通常使用Environment.ProcessorCount来获取当前的 CPU 计数并从那里开始工作:)