我们正在寻找用于处理图形文件的快速通用库,了解Google基准



如今,当神经网络耕Big大数据的时候,人工智能正在考虑让他在比特币上工作赚钱对他来说是否有利可图,我找到一个最快的开放式跨平台库来加载,保存和转码图形文件的任务看起来像是不合时宜的。 但是实际上,这项任务比以往任何时候都更加重要-对于计算机视觉和机器学习的所有技术,必须下载千兆字节的图片,有时中间数据必须另存为图像。 因此,以最快的方式做到这一点非常可取。 在本文中,我们将找到所需的库,最重要的是,我们将处理一个非常有用的产品,该产品可大大简化类似的任务和许多其他任务-Google Benchmark。

因此,问题的确切陈述是:在应用程序中,具有24位和8位色深的jpeg和tiff文件以及32位bmp被加载到内存中。 图像大小从微小(32x32像素)到大,分辨率为15K。 在此过程中,将修改文件,然后将它们以指定的格式保存到磁盘。 这应该通过跨平台的开源库来完成,该库在支持矢量指令AVX2的现代Intel处理器上具有最佳性能。 该库还支持DirectX DXT1压缩纹理格式库。 Windows Imaging Component被视为性能的基准-用于在Windows上处理图像的标准框架,也就是说,您需要找到一个与WIC相等或更快地工作的库。

但是最重​​要的要求是现在需要解决方案,但是昨天需要更好。

与库一起使用bmp,tiff和jpeg


解决方案从一个明显且简单的步骤开始,尽管步骤不是很迅速-对Wikileaks githubstackoverflow和其他google进行了深入研究,以寻找所需库的角色的合适候选人。 其中很少有:

  • FreeImage 。 著名图书馆Lib​​JPEG,LibPNG,LibTIFF的外壳。 DXT1支持通过插件提供。 缺点是API中jpeg保存的质量设置得过于分散-100、75.50和25%。 要更改此参数,您将必须理解和编辑代码。 该项目活跃且正在开发中-最新版本3.18.0已于2018年7月31日发布。Windows下的程序集微不足道,所有组件都是自动构建的。
  • Cimg代表一个古老的工件 ImageMagick包上的C ++头文件。 该软件包需要单独的构建安装,也可以绕过Cimg直接使用它。 使用图像有很多可能性:过滤器,转换,形态定义等。 支持HDR,不支持DXT1。
  • DevIL开发人员的图像库 )。 一个非常简单的OpenGL风格的C库。 它包含基于LibJPEG,LibPNG,LibTIFF的外壳,还具有广泛的内置功能,另外还支持许多图像格式,包括DXT1。 对于组装使用CMake。 大多数依赖项,包括LibJPEG,LibPNG,LibTIFF,都不包含在DevIL中,必须独立下载并单独编译。 关于构建系统的最新DevIL更新日期为01/01/2017,而上一个更新通常于2014年发生,因此,如果库可能存在问题,则其解决方案也可能存在问题。
  • OpenImageIO 。 它被定位为用于处理图像的专业软件的开发人员工具。 它以插件的形式支持与许多奇特的照片格式甚至视频一起使用。 Windows Build需要预编译的Boost和Qt4。尚无现成的组装版本可用于测试。
  • Boost GIL (通用图像库)Boost就是这样。 虽然不是全部。 该库还包含LibJPEG,LibPNG和LibTIFF的包装。
  • SDL_image 2.0与SDL库一起使用时,您会大笑,但其中还包含一个基于LibJPEG,LibPNG和LibTIFF的外壳。

使用Visual Studio编译器的最大优化级别和/ arch:AVX2开关,在Windows下编译了所有找到的库。

LibJPEG,LibPNG和LibTIFF库也是如此,以加快从新鲜的OpenCV库包中提取的工作。

符合Google基准


下一步的解决方案也是显而易见的-创建一个基准来比较发现的库的性能,并且使用Google Benchmark微基准测试库可以使它变得简单,快速。
Google Benchmark可以准确衡量您插入C ++ 11循环主体中的代码段的性能。

static void BM_foo1(benchmark::State& state) { //     Init_your_code(); for (auto _ : state){ //  -  your_code_to_benchmark(); } 

在注册为基准的功能中

 //       BENCHMARK(BM_foo1); 

并运行它们:

 BENCHMARK_MAIN(); 

然后以指定的格式发布报告-控制台输出,json,csv。

该报告将包含有关执行系统(处理器,缓存配置)的数据,每个测得功能的总全局运行时间以及占用处理器的时间。 这些时间通常不同-例如,第一时间包括读/写延迟,第二时间用于多线程基准测试是所有内核的工作时间之和。

Google基准测试显示的最后一个参数是该函数执行的迭代次数,这对于统计上正确地准确测量其运行时间是必需的。 系统自行选择它,进行初步测量。

什么是运行时间的“准确度量”? 您可以撰写有关该主题的论文,但在这种情况下,只需说一下:

  • 默认情况下,测量是在处理器集群中进行的,也就是说,准确度的理论顺序就是这样。 默认输出以纳秒为单位;
  • 我看到的所有测试的结果从发布到发布都非常稳定;
  • 根据我的情报数据,世界上最大的汽车问题之一的车载计算机软件的开发人员使用并完全信任Google基准。 所以我们会相信。

唯一需要注意的是:Google基准测试不提供基准测试迭代开始之间的缓存“清理”。 如有必要,您应该自己做。

但是Google基准测试可以做很多其他事情:

  • 计算算法的渐近复杂度(O);
  • 在多线程基准测试中正常工作,不是在处理器滴答声中而是在“实时”模式(挂钟)下测量其持续时间;
  • 使用您自己的“手动”时间测量功能,该功能可能有用,例如,在GPU上测量工作时;
  • 针对被测函数的给定主体,使用不同的参数集自动设置基准;
  • 显示基准的多个起点的平均值,中位数和标准差;
  • 设置自己的计数器和标签,这些计数器和标签将反映在Google基准报告中。

Google基准测试是从github存储库下载的, 使用Cmake(适用于Windows的Visual Studio程序集)为适当的平台进行了组装,生成的库将链接到您的项目(在Windows中,还需要与shlwapi库的链接),基准测试头文件已添加到您的代码中.h,之后所有操作均如上所述。

如果它不起作用,那么除了已经指明的网站之外,唯一的地方是专门的产品论坛 ,您至少可以在此获得有关Google基准的信息和帮助。

在我们的情况下,一切正常进行。 与客户沟通后,定义了4个基准,它们以不同的名称加载和保存:

  • 分辨率为15k的8位jpeg文件
  • 分辨率为15k的24位jpeg文件
  • 分辨率为15k的24位tiff文件
  • 分辨率为32x32的32位bmp文件

达到结果


最初计划所有找到的库,即FreeImage,Cimg,DevIL,OpenImageIO,Boost GIL和SDL_image 2.0,都将与Windows Imaging Component(WIC)进行测试比较。 但是,如果在前三个库中找不到所需的库,则在紧急情况下,客户要求依赖于Boost和SDL等“怪物”的后三个库保留储备。 而且,幸运的是,她被发现了。 虽然不是立即。

以下是Google基准测试生成的报告,该报告显示:

  • 在所有测试中,FreeImage完全具有令人沮丧的分数都失去了WIC,因此不再被考虑。
  • Cimg在所有地方都干净利落地失去了WIC,只是加载tiff的速度略快(不到5%)。 las,他也将被删除。 此外,这适用于直接使用ImageMagick软件包。

保留DevIL库。 在加载bmp和tiff(分别是WIC的3和2.8倍!),黑白jpeg(比WIC更好的1.75倍)的情况下,它显示出出色的结果,但是在加载常规的24位jpeg时会变慢一些-它的加载速度是3比WIC慢%。
08/15/18 11:15:44
Running c:\WIC\WIC_test\Release\WIC_test.exe
Run on (8 X 4008 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 262K (x4)
L3 Unified 8388K (x1)
BenchmarkTimeCPUIterations
BM_WIC8jpeg72 ms70 ms11
BM_cimg8jpeg562 ms52 ms10
BM_FreeImage8jpeg147 ms144 ms5
BM_devIL8jpeg41 ms41 ms17
BM_WIC24jpeg266 ms260 ms3
BM_cimg24jpeg656 ms128 ms6
BM_FreeImage24jpeg594 ms594 ms1
BM_devIL24jpeg276 ms276 ms3
BM_WIC24tiff844 ms844 ms1
BM_cimg24tiff808 ms131 ms5
BM_FreeImage24tiff953 ms938 ms1
BM_devIL24tiff305 ms305 ms2
BM_WIC323 ms3 ms236
BM_cimg3271 ms7 ms90
BM_FreeImage326 ms5 ms112
BM_devIL321 ms1 ms747
当然,DevIL也可以在此阶段被拒绝,但是此处另一个框架出现在Libjpeg-turbo框架中。

掌声可轻松满足其输出-Libjpeg-turbo是一个跨平台的库,完全实现了libjpeg功能(API)并添加了自己的功能(例如,使用32位缓冲区)。 同时,对于x86架构,Libjpeg-turbo积极使用矢量指令(SSE2,AVX2),并且据其创建者称,它比libjpeg(!)快2-6倍。

因此,下一步是使用Libjpeg-turbo而非libjpeg构建DevIL。 在CMake的帮助下,Libjpeg-turbo可以毫无问题地构建Visual Studio,然后几乎立即(替换唯一的#define,它确定了DevIL头文件中libjpeg的版本),它开始作为DevIL的一部分工作。

结果,Google基准报告如下所示:
BenchmarkTimeCPUIterations
BM_WIC8jpeg72 ms68 ms9
BM_cimg8jpeg565 ms39 ms10
BM_FreeImage8jpeg148 ms141 ms5
BM_devIL8jpeg31 ms31 ms24
BM_WIC24jpeg269 ms266 ms2
BM_cimg24jpeg675 ms131 ms5
BM_FreeImage24jpeg604 ms594 ms1
BM_devIL24jpeg149 ms150 ms5
BM_WIC24tiff833 ms828 ms1
BM_cimg24tiff785 ms138 ms5
BM_FreeImage24tiff943 ms938 ms1
BM_devIL24tiff318 ms320 ms2
BM_WIC324 ms3 ms236
BM_cimg3274 ms8 ms56
BM_FreeImage326 ms5 ms100
BM_devIL321 ms1 ms747
当然,与jpeg相比,使用jpeg进行性能改进甚至还没有达到两倍,但是应该是这样-因为速度优势仅适用于jpeg编码/解码,并且测试包括读取/写入文件的开销。

但是可以看出,在8位jpeg 2.3倍,24位jpeg 1.8倍,24位tiff- 2.7倍,32位bmp- 3.5倍的情况下,平均DevIL比WIC更快。

问题解决了。 这个决定完全花费了三个暑假前的工作日。 当然,如果还有更多的话,那么有可能会有一个图书馆带来更令人印象深刻的结果,而如果还有更多的话,那么也许我会写我自己在寻找的图书馆。

但是,即使是令人印象深刻的。 因此,如果您正在寻找一种跨平台的库来处理图形文件,这些库在各个方面都非常快捷,容易,那么请注意DevIL ,如果您需要快速而准确地对代码进行比较测量,则可以使用Google基准测试

Source: https://habr.com/ru/post/zh-CN425021/


All Articles