【发布时间】:2012-07-04 00:33:08
【问题描述】:
我们的网络服务器需要一起处理许多大图像的组合,然后再将结果发送给网络客户端。此过程对性能至关重要,因为服务器每小时可以接收数千个请求。
现在,我们的解决方案从 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 图像并将它们合成在一起。这将大致对应于我们将在生产环境中获得的请求类型。
- 合成中使用的每张图片的大小均为 1600x1600。
- 该解决方案将涉及多达 10 台负载平衡服务器,就像我们在此讨论的那样。因此,额外的软件开发工作可能值得节省硬件成本。
- 我们正在考虑缓存解码后的源图像,但每个合成很可能使用完全不同的源图像完成,因此缓存未命中率较高,而性能增益较低。
- 基准测试是使用糟糕的显卡完成的,因此我们可以预期 PNG 解码使用像样的显卡会成为更大的性能瓶颈。
【问题讨论】:
-
+1 用于实际分析
-
您是否尝试过不同的 PNG 编码以查看对性能的影响(隔行扫描、24 位、效率较低的压缩)
-
@sboisse 另一种选择是缓存未压缩的图像。我会统计一下使用了哪些图像以及何时使用,然后检查缓存命中率。如果你为磁盘上的缓存分配了 10 GB 的空间,那就是 1,000 个图像。
-
我会将图像存储为二进制、预解码的文件,您可以立即加载并提供给 GPU。如果它们每个占用 10MB,那么每 TB 可以存储近 100,000 个(我修正了我的数学)
-
@sboisse 我没有说缓存作品,而是解码后的源图像(最慢的步骤)。完全按照亚历克斯的建议。
标签: c# performance png decode decoding