1前言
1.1优化目标
人脸识别(FaceRecognition)服务运行在Windows系统的bat文件中,其计算量非常大,运行耗时也比较长(10-20小时),并且在Java程序中使用Runtime执行命令,比直接运行cmd命令耗时更多,因此必须采取必要的手段对整个Server进行优化。
主要优化目标是降低Java程序中的执行时间,以提高吞吐率。
1.2系统环境
1.2.1硬件环境
Server类型
虚拟机
CPU
1核,Intel(R) Xeon(R) CPU E5603 @ 1.60GHz
内存
3GB
1.2.2软件环境
操作系统
Windows XP Pro Version 2002 SP3
Tomcat
apache-tomcat-7.0.47-windows-x86
JDK
jdk1.7.0_04
1.3潜在优化点分析
下面,搭建模拟环境,分析潜在的优化点。
1.3.1加大Java VM内存
加内存,catalina.bat中加上Java VM参数:
set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256m
下面是Tomcat添加JVM参数之后的对比结果(测试ffmpeg命令):
默认内存(64M)
85 s
加大内存(1024M)
85 s
可见,优化内存,基本无效。
1.3.2优化执行命令的Java方法
仍然采用上面的测试例子,不同方法的执行时间对比如下:
命令行中直接执行bat文件
69s
使用RunTime,不加cmd /c start
104s
使用RunTime,加cmd /c start,内存为64M
85s
使用RunTime,加cmd /c start,内存加大到512M
85s
使用processBuilder,不加cmd /c start
88s
使用processBuilder,加cmd /c start
87s
使用processBuilder,加cmd /c
87s
优化后,运行时间提升幅度为(104-85)/104*100%=18.27%。
1.3.3屏蔽输出
直接执行,输出信息
80s
直接执行,不输出信息
72s
优化后,运行时间提升幅度为(80-72)/80*100%=10%。
1.3.4CPU优化
1核2.4GHz
292s
4核2.5GHz
69s
优化后,运行时间提升幅度为(292-69)/292*100%=76.37%。
1.3.5Java Runtime优化
在Java程序中使用Runtime执行操作系统命令的时候,发现java程序的CPU占用率高达66%,而执行的命令程序只占33%,因此需要考虑优化Runtime方法的执行。
优化方法:将执行命令的方法中启动的两个用于读取输出和错误流的线程去掉,改为直接读取这两个流,而不是启动2个线程。
优化前后对比如下:
测试项
优化前
优化后
Linux
直接在cmd中执行耗时
347s
344s
在Java中使用Runtime执行耗时
728s
353s
CPU占用率
ffmpeg:33%
Javaw:66%
ffmpeg:66%
Javaw:33%
Windows
直接在cmd中执行耗时
87s
86s
在Java中使用Runtime执行耗时
107s
88s
CPU占用率
ffmpeg:20%
Javaw:40%
ffmpeg:40%
Javaw:0%
优化后,运行时间提升到和直接执行命令相当的水平。
2优化过程
搭建测试环境
记录命令行上的执行时间;
记录Java程序中的执行时间;
按照优化点分析进行优化,分别记录优化之后的执行时间;
生成优化报告,并记录详细的优化步骤,供后续使用。
2.1搭建测试环境
1)搭建人脸识别的运行环境。
2)由于人脸识别步骤耗时较长,为了便于快速进行优化测试,准备一个24秒长的电影片段,总共包含4个人脸,并且每一帧都会有至少一个人脸。
2.2在命令行中执行
在CMD中执行下面的命令,以手动启动人脸检测步骤。
C:\Face.bat Y:\FaceRecognition\DispatcherMovies\face.avi
记录命令执行前后的时间如下:
The current time is: 18:11:04.52
The current time is: 18:19:29.09
总计执行504秒。
2.3在Java程序中执行
Java程序中采用“Runtime.getRuntime().exec(cmd)”的方式执行Windows操作系统的DOS命令,其中命令前面加上“cmd /c start”参数,以提高执行效率。
记录命令执行前后的时间如下:
The current time is: 13:54:15
The current time is: 14:21:12
总计执行1617秒。
2.4性能优化
2.4.1内存优化
将默认的64M内存加大为1024M。在catalina.bat中加上Java VM参数:
set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=128M -XX:MaxPermSize=256m
记录命令执行前后的时间如下:
The current time is: 14:27:23
The current time is: 14:50:18
总计执行1375秒。
2.4.2屏蔽输出
将人脸识别bat文件中输出全部屏蔽掉,在bat文件中每个命令的后面加上“> nul”参数。
记录命令执行前后的时间如下:
The current time is: 15:17:09
The current time is: 15:39:15
总计执行1326秒。
2.4.3CPU优化
只增加CPU数量,不增加CPU主频
将原来的1核CPU扩展到8核CPU。CPU配置为:Intel(R) Xeon(R) CPU E5603 @ 1.60GHz。
记录命令执行前后的时间如下:
The current time is: 21:51:55
The current time is: 22:00:38
总计执行523秒。
既增加CPU数量,又增加CPU主频
将原来的1核CPU扩展到32核CPU。CPU配置由1.60GHz变为2.13GHz。
记录命令执行前后的时间如下:
The current time is: 10:35:07
The current time is: 10:41:21
总计执行374秒。
2.4.4Java Runtime优化
优化前后对比如下:
测试项
优化前
优化后
直接在cmd中执行
245s
245s
在Java中使用Runtime执行
374s
239s
优化后,运行时间提升到和直接执行命令相当的水平。
3优化结果
3.1结果对比
3.1.1优化结果对比
对于测试环境中的24秒的视频,性能优化前后的测试结果对比如下表所示:
优化场景
耗时
120分钟视频处理耗时
CPU:1核1.6GHz,命令行中直接执行
504s
2520分钟(42小时)
CPU:1核1.6GHz,在Java程序中执行,并且添加“cmd /c start”参数
1617s
8085分钟(134.75小时)
CPU:1核1.6GHz,Java VM内存由默认的64M增加到1024M
1375s
6875分钟(114.58小时)
CPU:1核1.6GHz,执行的bat命令屏蔽输出
1326s
6630分钟(110.5小时)
CPU由1核(1.6GHz)扩展到8核(1.6GHz)
523 s
2615分钟(43.58小时)
CPU由1核(1.6GHz)扩展到8核(2.13GHz),直接在cmd中执行命令
245s
1225分钟(20.42小时)
CPU由1核(1.6GHz)扩展到8核(2.13GHz),在Java程序中执行
374 s
1870分钟(31.17小时)
CPU由1核(1.6GHz)扩展到8核(2.13GHz),优化Runtime方法后,在Java程序中执行
239s
1195 分钟(19.92小时)
说明:
1)上述的优化步骤,是一步步进行的,也就是说,后面的步骤已经包含前面的优化步骤,因此最后一步的优化结果就是最终的优化结果;
2)“120分钟视频处理耗时”是按比例计算出来的理论值,而非实测值;
3)测试环境中的视频每一帧均至少包含一个人脸,而实际的视频并非如此,而是会有所减少。
3.1.2不同CPU核数情况下的对比
测试1、2、4、8个CPU核数的情况,结果如下:
CPU
cmd执行时间
Runtime优化前
Runtime优化后
CPU占用率
1核1.60GHz
504s
1326s
510s
97%
1核2.13GHz
239s
1266s
203s
97%
2核2.13GHz
241s
155s
255s
48%
4核2.13GHz
249s
147s
144s
24%
8核2.13GHz
245s
153s
237s
13%
3.2结论
人脸识别程序直接在命令行中执行的时候耗时较短,但是在Java程序中执行的话耗时较多(大约是原来的3倍),经过一系列的优化,在Java程序中运行时间已经降低到了原始命令行中执行时间以下;
人脸识别工具是CPU严重依赖型的程序,当提高CPU数量和性能的时候,执行时间会大幅降低,相应的吞吐率会大幅提高。因此,需要提高人脸识别的吞吐率的时候,主要考虑的途径是提高CPU的整体性能;
优化Java的Runtime方法的执行,降低Java自身的CPU占用率,也可以大幅提高人脸识别工具的性能。但是,此方法对于单核CPU效果比较明显,对于多核CPU效果较小;
FaceRecognition是单线程应用,单纯的增加CPU的核数并无太大的作用,可以考虑增加单个CPU的处理能力;