入门指南#
为了利用 RDMA 和 ATS 实现高性能计算,本指南概述了以下步骤
配置 NVIDIA ConnectX-6 Dx 以支持 RoCE
在 VMware ESXi 和虚拟机上启用 ATS
在 NVIDIA ConnectX-6 DX 网卡上启用 ATS
配置 NUMA 亲缘性
创建用于多节点训练的 Docker 文件
在多节点集群上的虚拟机之间设置无密钥登录
运行 ResNet-50 多节点训练示例
配置 NVIDIA ConnectX-6 Dx 网卡和 Spectrum 交换机以支持 RoCE#
为了利用 RoCE,NVIDIA ConnectX-6 Dx 网卡必须在基于 DSCP 的 QoS 模式下的丢包网络上运行 RoCE。以下知识库文章是应用此配置的有用资源:https://community.mellanox.com/s/article/lossless-roce-configuration-for-mlnx-os-switches-in-dscp-based-qos-mode
在本指南中,我们将参考知识库文章中针对 3.8.2008 及更高版本的配置步骤。
在 NVIDIA 交换机上运行以下命令
switch (config) # roce
注意
RoCE 功能已实现自动化,因此在无损网络上运行 RoCE 所需的全部操作就是运行
roce
命令。创建一个隔离的 vLAN,并将 NVIDIA ConnectX 网卡作为接入端口放入创建的 vLAN 中。连接到交换机端口 1/1 - 1/4 的四台服务器。
1switch (config) # interface vlan 111 2switch (config vlan 111) # exit 3switch (config) # interface ethernet 1/1-1/4 switchport access vlan 111
将接口上的 MTU 设置为 9216(在 3.9.2110 以下版本中,交换机的默认 MTU 为 1500)。
1switch (config) # interface ethernet 1/1-1/4 shutdown 2switch (config) # interface ethernet 1/1-1/4 mtu 9216 3switch (config) # interface ethernet 1/1-1/4 no shutdown
可选,如果您运行的是 Cumulus Linux,请按照以下说明启用 RoCE:https://docs.cumulusnetworks.com/cumulus-linux-42/Network-Solutions/RDMA-over-Converged-Ethernet-RoCE/。
在 VMware ESXi 和虚拟机上启用 ATS#
为了通过高性能实现对等 (P2P),我们将通过更新 VMKernel,然后更新 VM 配置来启用 ATS。
更新 VMKernel 以支持对等 (P2P)。
要启用 ATS 启动选项,请调用以下命令并重新启动 ESXi
esxcli system settings kernel set -s atsSupport -v TRUE
重新启动后验证值是否正确,调用
esxcli system settings kernel list -o atsSupport
输出应类似于以下内容
1Name Type Configured Runtime Default Description 2------------ ------- ---------- ------- ------- ----------- 3atsSupport Bool TRUE TRUE FALSE Enable Support for PCIe ATS
更新 VM 配置以支持 P2P。
编辑 VM 配置设置
1pciPassthru.allowP2P=true # enable P2P 2pciPassthru.RelaxACSforP2P=true # update ACS capabilities in switch
注意
当启用为 P2P 放宽 ACS 时,VMware 将找到支持 ATS 的直通设备,找到其父交换机,并启用 ACS 直接转换位。之前关于对等网络设备的所有功能必须提供给单个 VM 的限制已被取消。对等设备的每个功能都可以提供给单独的 VM。
如果存在多个 GPU 物理设备,VM 可以使用现有配置为 P2P 指定特定设备
pciPassthru0.cfg.gpu-pci-id = "ssss:bb:dd.f"
注意
gpu-pci-id
是十六进制 SBDF 格式。如果 GPU 处于 SR-IOV 模式,则应指定 VF 地址。
在 NVIDIA ConnectX-6 Dx 网卡上启用 ATS#
使用以下命令安装 python 2.7
sudo apt-get install python
下载并安装 MLNX OFED 5.0:https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/。
选择(操作系统/版本/架构)并下载 tar 文件,例如:(Ubuntu/20.04/x86_64)。
下载后,将软件包复制到 VM,并运行以下命令解压并安装
1tar xvf MLNX_OFED_LINUX-5.2-2.2.4.0-ubuntu20.04-x86_64.tgz 2cd MLNX_OFED_LINUX-5.2-2.2.4.0-ubuntu20.04-x86_64.tgz 3sudo ./mlnxofedinstall
注意
上述步骤还将更新所有 CX5 或 CX6 卡的固件。
安装完成后运行以下命令
sudo /etc/init.d/openibd restart
注意
在安装过程中,将检测到 CX-6 网卡,并且 OFED 应更新固件。如果失败,请下载最新的固件并手动更新。之后重复 OFED 安装。
使用以下命令检查 OFED 和固件版本
1dpkg -l | grep mlnx-ofed 2cat /sys/class/infiniband/mlx5*/fw_ver
启动 Mellanox 软件工具
sudo mst start
使用以下命令检查 CX-6 网卡的 ATS_ENABLED 配置状态。您应该看到类似于以下的输出
1sudo mlxconfig -d /dev/mst/mt4123_pciconf0 query | grep -i ATS 2ATS_ENABLED False(0)
如果不存在,则固件不支持 ATS。请更新到支持 ATS 的固件版本。如果设置为 False,请使用以下命令启用 ATS
1sudo mlxconfig -d /dev/mst/mt4123_pciconf0 set ATS_ENABLED=true 2Device #1: 3---------- 4Device type: ConnectX6 5Name: MCX653105A-HDA_Ax 6Description: ConnectX-6 VPI adapter card; HDR IB (200Gb/s) and 200GbE; single-port QSFP56; PCIe4.0 x16; tall bracket; ROHS R6 7Device: /dev/mst/mt4123_pciconf0 8 9Configurations: Next Boot New 10ATS_ENABLED False(0) True(1) 11Apply new Configuration? (y/n) [n] : y 12Applying... Done! 13-I- Please reboot machine to load new configurations.
在两个虚拟机上的 CX-6 上都启用 ATS 后,将主机置于维护模式并重新启动 ESXi 主机。
注意
如果您在两台主机之间配置了 vMotion,则主机上的虚拟机可以在主机重新启动以启用 ATS 时移动到另一台正在运行的主机。
注意
请记住重新提交命令以在 PCIe 交换机上启用 ACS 直接转换位。
ESXi 主机重新启动完成后,重新启动 vCenter 和虚拟机。
接下来,通过运行以下命令验证虚拟机上是否已启用 ATS
1sudo mst start 2sudo mlxconfig -d /dev/mst/mt4123_pciconf0 query | grep -i ATS 3sudo lspci -vvv
搜索 Mellanox CX-6 设备,并验证输出是否包含如下配置的 ATS Capability
1Capabilities: [480 v1] Address Translation Service (ATS) 2 ATSCap: Invalidate Queue Depth: 00 3 ATSCtl: Enable+, Smallest Translation Unit: 00
注意
Enable+ 表示已成功启用。
配置虚拟机的 NUMA 亲缘性#
检查您的网卡和 GPU 连接到哪个 NUMA 节点,在 ESXi 主机上运行以下命令
1esxcli hardware pci list | grep -A 30 -B 10 NVIDIA 2esxcli hardware pci list | grep -A 30 -B 10 Mellanox
以下输出描述了设备的 NUMA 节点
10000:3b:02.3 2 Address: 0000:3b:02.3 3 Segment: 0x0000 4 Bus: 0x3b 5 Slot: 0x02 6 Function: 0x3 7 VMkernel Name: PF_0.59.0_VF_15 8 Vendor Name: NVIDIA Corporation 9 Device Name: NVIDIAA100-PCIE-40GB 10 Configured Owner: VMkernel 11 Current Owner: VMkernel 12 Vendor ID: 0x10de 13 Device ID: 0x20f1 14 SubVendor ID: 0x10de 15 SubDevice ID: 0x0000 16 Device Class: 0x0302 17 Device Class Name: 3D controller 18 Programming Interface: 0x00 19 Revision ID: 0xa1 20 Interrupt Line: 0xff 21 IRQ: 255 22 Interrupt Vector: 0x00 23PCI Pin: 0xff 24 Spawned Bus: 0x00 25 Flags: 0x0001 26 Module ID: 54 27 Module Name: nvidia 28 Chassis: 0 29 Physical Slot: -1 30 Slot Description: 31 Device Layer Bus Address: s00000001.00.vf15 32 Passthru Capable: true 33 Parent Device: PCI 0:58:0:0 34 Dependent Device: PCI 0:59:2:3 35 Reset Method: Function reset 36 FPT Sharable: true 37 NUMA Node: 0 38 Extended Device ID: 65535 39 Extended Device Name:
确保网卡和 GPU 位于同一 NUMA 节点上。
在 VM 配置中,添加新的键值对
numa.nodeAffinity = <numa node value>
创建用于多节点训练的 Docker 文件#
按照以下 Dockerfile 创建 Docker 镜像
1FROM nvcr.io/nvaie/tensorflow:21.07-tf1-py3 2 3ARG DEBIAN_FRONTEND=noninteractiv 4 5# Set MOFED version, OS version and platform 6ENV MOFED_VERSION 5.2-2.2.4.0 7 8#http://content.mellanox.com/ofed/MLNX_OFED-5.2-2.2.4.0/MLNX_OFED_LINUX-5.2-2.2.4.0-ubuntu20.04-x86_64.tgz 9ENV OS_VERSION ubuntu20.04 10 11ENV PLATFORM x86_64 12 13 14RUN pip3 install --user --upgrade pip && \ 15 pip3 install --no-cache-dir absl-py 16 17RUN apt-get update && \ 18 apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \ 19 apt-utils build-essential cmake tcsh tcl tk \ 20 make git curl vim wget ca-certificates \ 21 iputils-ping net-tools ethtool \ 22 perl lsb-release python-libxml2 \ 23 iproute2 pciutils libnl-route-3-200 \ 24 kmod libnuma1 lsof openssh-server \ 25 swig libelf1 automake libglib2.0-0 \ 26 autoconf graphviz chrpath flex libnl-3-200 m4 \ 27 debhelper autotools-dev gfortran libltdl-dev \ 28 dmidecode build-essential cmake git zip pciutils hwloc numactl \ 29 dpatch bison pkg-config numactl dkms udev libnl-route-3-dev libnl-3-dev \ 30 libmnl0 libmnl-dev expect-dev ncat \ 31 usbutils iperf3 bc tree \ 32 quilt \ 33 landscape-common libpci-dev && \ 34 rm -rf /var/lib/apt/lists/* 35# hugepages libgfortran3 netcat 36# linux-headers-$(uname -r) 37 38 39WORKDIR /workspace 40RUN wget http://content.mellanox.com/ofed/MLNX_OFED-${MOFED_VERSION}/MLNX_OFED_LINUX-$MOFED_VERSION-$OS_VERSION-$PLATFORM.tgz && \ 41 tar -xvf MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}.tgz && \ 42 MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/mlnxofedinstall --user-space-only --without-fw-update --force && \ 43 tree /workspace/MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/ 44 #dpkg -i /workspace/MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/DEBS/libibumad-dev*.deb && \ 45 #dpkg -i /workspace/MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/DEBS/libibumad3*.deb 46 47 48# MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/mlnxofedinstall --dpdk --upstream-libs --without-fw-update --force --umad-dev-rw -q 49#--user-space-only 50# MLNX_OFED_LINUX-${MOFED_VERSION}-${OS_VERSION}-${PLATFORM}/mlnxofedinstall --dpdk --without-fw-update --force -q 51 52#WORKDIR /workspace 53#RUN wget https://www.mellanox.com/downloads/MFT/mft-4.16.1-9-x86_64-deb.tgz && \ 54#tar xzvf mft-4.16.1-9-x86_64-deb.tgz&& \ 55#cd mft-4.16.1-9-x86_64-deb && \ 56#./install.sh 57 58 59WORKDIR /workspace 60RUN git clone -b cnn_tf_v1.15_compatible https://github.com/tensorflow/benchmarks.git 61 62 63WORKDIR /workspace 64RUN git clone https://github.com/NVIDIA/nccl-tests && \ 65cd nccl-tests && \ 66make MPI=1 MPI_HOME=/usr/local/mpi 67 68 69WORKDIR /workspace 70RUN git clone https://github.com/linux-rdma/perftest && \ 71 cd perftest && \ 72 ./autogen.sh && \ 73 CUDA_H_PATH=/usr/local/cuda/include/cuda.h ./configure && \ 74 make install 75 76 77 78WORKDIR /test 79 80 81RUN rm -f ${_CUDA_COMPAT_PATH}/.*.checked
运行以下命令,在与 Dockerfile 相同的文件夹中构建 docker 多节点容器
sudo docker build -t multinode:latest .
标记镜像并将其上传到您的 NVIDIA AI Enterprise 私有注册表
1sudo docker tag multinode <NVIDIA_AI_Enterprise_private_registry_username>/multinode 2sudo docker push
在多节点集群上的虚拟机之间设置无密钥登录#
在全新安装的系统上,~/.ssh
目录通常为空。但是,将使用本指南中的步骤生成/添加以下文件
- id_rsa 和 id_rsa.pub
用于节点之间无密钥登录的 SSH 密钥。
- authorized_keys
服务器识别的来自其他节点/系统的 RSA 公钥列表,用于 ssh 访问。
- config
创建的文件,用于在访问其他节点时提供 ssh 安全密钥检查设置。
- mpicont.sh
我们将创建的脚本,用于允许 mpi 在不同节点上的容器之间通信。
- ssh_container/
一个目录,包含上述文件,但用于节点间容器通信。
- known_hosts
此文件由 ssh 自动生成,并列出用户曾经连接的所有主机的密钥。
生成 SSH 密钥#
在主节点上,我们将创建一对在节点之间共享的 ssh 密钥。然后将生成另一对密钥,用于在节点之间运行的容器之间使用。在本指南中,我们将相应地命名每组密钥,但默认密钥名称 id_rsa
和 id_rsa.pub
也可以。
主机/工作节点 SSH 密钥#
在命令行终端中,创建一个新的 SSH 密钥
ssh-keygen -t rsa
输入要保存密钥的文件 (/home/nvidia/.ssh/id_rsa)
id_rsa_host
这将生成以下文件
id_rsa_host
id_rsa_host.pub
容器 SSH 密钥#
创建一个名为
ssh_container
的目录。此目录可以创建在任何位置,但在此示例中,我们将其放在~/.ssh
目录中1mkdir ssh_container 2cd ssh_container 3ssh-keygen -t rsa
输入要保存密钥的文件 (
/home/nvidia/.ssh/id_rsa
)<path/to>/ssh_container/id_rsa_cont
在 ssh_container
目录中,这将生成
id_rsa_cont
id_rsa_cont.pub
创建用于无密钥登录的配置文件#
在我们的实验室环境中,Ubuntu 虚拟机的用户名是 nvidia
。请在以下步骤中替换用户名以反映您环境中的用户。在主节点上,创建一个名为 config
的文件 (~/.ssh/config
),并放入以下内容
1Host *
2 User nvidia
3 IdentityFile ~/.ssh/id_rsa_host
4 StrictHostKeyChecking no
5 UserKnownHostsFile=/dev/null
在 ssh_container
目录 (~/.ssh/ssh_container/config
) 中,为容器之间的无密钥登录创建另一个 config
文件
1Host *
2 User nvidia
3 IdentityFile /root/.ssh/id_rsa_cont
4 StrictHostKeyChecking no
5 UserKnownHostsFile=/dev/null
6 LogLevel=Error
7 ServerAliveInterval=30
创建 mpicont.sh 脚本#
在
~/.ssh
目录中,创建一个名为mpicont.sh
的脚本,内容如下1mpicont.sh 2docker exec mpicont /bin/bash -c "$SSH_ORIGINAL_COMMAND"
然后使脚本可执行
chmod +x mpicont.sh
将 ~/.ssh
复制到工作节点并确认无密钥登录#
现在我们可以将主节点的 ~/.ssh
目录中的所有文件复制到我们在节点列表中指定的所有工作节点。
scp -r .ssh $<worker_node_IP>:/home/nvidia/.ssh/;done
更改所有节点上 ssh_container
中的权限#
在所有节点上,更改 ssh_container/config
文件的所有权,使所有者为 root
sudo chown root:root config
然后将 ssh_container
文件夹中所有文件的权限更改为 600。
sudo chmod 600 *
以下是复制到工作节点的所有文件及其正确权限的列表
1~/.ssh$ ll *
2-rw------- 1 nvidia nvidia 894 Jan 24 17:46 authorized_keys
3-rw-r--r-- 1 nvidia nvidia 125 Jan 24 14:21 config
4-rw------- 1 nvidia nvidia 1675 Jan 24 14:19 id_rsa_host
5-rw-r--r-- 1 nvidia nvidia 396 Jan 24 14:19 id_rsa_host.pub
6-rwxrwxr-x 1 nvidia nvidia 57 Jan 24 15:55 mpicont.sh*
ssh_container
:
1total 24
2drwxrwxr-x 2 nvidia nvidia 4096 Feb 6 16:50 ./
3drwxrwxr-x 4 nvidia nvidia 4096 Feb 7 11:29 ../
4-rw------- 1 nvidia nvidia 396 Jan 24 15:58 authorized_keys
5-rw------- 1 root root 161 Jan 24 17:54 config
6-rw------- 1 nvidia nvidia 1675 Jan 24 15:58 id_rsa_cont
7-rw------- 1 nvidia nvidia 396 Jan 24 15:58 id_rsa_cont.pub
现在在所有工作节点上运行 Docker 容器,使用以下命令
sudo docker run -it --gpus=all --net=host --uts=host --ipc=host --ulimit stack=67108864 --ulimit memlock=-1 --shm-size=1g --name=mpicont --device=/dev/infiniband -v /home/nvidia/.ssh/ssh_container:/root/.ssh <NVIDIA_AI_Enterprise_private_registry_username>/multinode:latest sleep infinity
在主节点上,运行
sudo docker run -it --gpus=all --net=host --uts=host --ipc=host --ulimit stack=67108864 --ulimit memlock=-1 --shm-size=1g --name=mpicont --device=/dev/infiniband -v /home/nvidia/.ssh/ssh_container:/root/.ssh <NVIDIA_AI_Enterprise_private_registry_username>/multinode:latest /bin/bash
要测试 ssh 无密钥 mpi 命令是否正在运行,请根据您拥有的工作节点数量运行以下命令
mpirun --allow-run-as-root -H <master_IP>,<worker1_IP>,<worker2_IP>,<worker3_IP> -np "4" hostname
要验证所有工作节点上的可用 GPU,请运行以下命令
mpirun --allow-run-as-root -H <worker1_IP>,<worker2_IP>,<worker3_IP> -np "3" nvidia-smi
注意
在我们的实验室环境中,np
(进程数,或者换句话说,GPU 数量)参数为 4。请修改 np
参数以反映您的环境。
输出应反映所有四个节点的主机名。
安装 nv_peer_memory#
在每个节点上安装 nv_peer_mem 模块。
git clone https://github.com/Mellanox/nv_peer_memory.git
cd nv_peer_memory
./build_module.sh
cd /tmp
tar xzf /tmp/nvidia-peer-memory_1.0.orig.tar.gz
cd nvidia-peer-memory-1.0
dpkg-buildpackage -us -uc
dpkg -i <path to generated deb files>
运行 ResNet-50 多节点训练示例#
注意
确保 ssh 无密钥 mpi 正在运行,命令如下
mpirun --allow-run-as-root -H <master_IP>,<worker1_IP>,<worker2_IP>,<worker3_IP> -np "4" hostname
运行以下命令以测试 ResNet-50 多节点基准测试示例,具体取决于工作节点计数
mpirun --allow-run-as-root -H <master_IP>,<worker1_IP>,<worker2_IP>,<worker3_IP> -np "4 " -x NCCL_IB_DISABLE=0 -x NCCL_DEBUG=INFO python3 /workspace/benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model resnet50 --batch_size 512 --use_fp16 --variable_update=horovod --xla=True
解释结果#
此基准测试报告每次报告迭代的每秒图像数训练性能。使用最后几个报告的值来表示训练性能。
1Done warm up
2Step Img/sec total_loss
3Done warm up
4Step Img/sec total_loss
5Done warm up
6Step Img/sec total_loss
7Done warm up
8Step Img/sec total_loss
91 images/sec: 2100.6 +/- 0.0 (jitter = 0.0) 7.738
101 images/sec: 2100.8 +/- 0.0 (jitter = 0.0) 7.742
111 images/sec: 2100.2 +/- 0.0 (jitter = 0.0) 7.734
121 images/sec: 2100.8 +/- 0.0 (jitter = 0.0) 7.770
1310 images/sec: 2100.0 +/- 61.9 (jitter = 6.6) 7.607
1410 images/sec: 2100.4 +/- 60.4 (jitter = 189.7) 7.656
1510 images/sec: 2100.9 +/- 59.2 (jitter = 88.7) 7.611
1610 images/sec: 2100.9 +/- 59.0 (jitter = 175.8) 7.647
1720 images/sec: 2100.2 +/- 39.4 (jitter = 92.3) 7.527
1820 images/sec: 2100.2 +/- 43.8 (jitter = 198.3) 7.515
1920 images/sec: 2100.1 +/- 41.1 (jitter = 181.8) 7.512
2020 images/sec: 2100.1 +/- 43.0 (jitter = 14.7) 7.501
2130 images/sec: 2100.9 +/- 34.9 (jitter = 198.3) 7.490
2230 images/sec: 2100.4 +/- 35.3 (jitter = 11.1) 7.474
2330 images/sec: 2100.7 +/- 33.3 (jitter = 92.9) 7.483
2430 images/sec: 2100.3 +/- 34.9 (jitter = 157.3) 7.493
2540 images/sec: 2100.5 +/- 28.3 (jitter = 76.4) 7.476
2640 images/sec: 2100.9 +/- 31.2 (jitter = 193.8) 7.476
2740 images/sec: 2100.5 +/- 31.2 (jitter = 186.9) 7.483
2840 images/sec: 2100.2 +/- 31.5 (jitter = 18.9) 7.474
2950 images/sec: 2100.8 +/- 28.1 (jitter = 15.0) 7.480
3050 images/sec: 2100.3 +/- 28.3 (jitter = 168.8) 7.468
3150 images/sec: 2100.7 +/- 25.7 (jitter = 76.4) 7.485
3250 images/sec: 2100.2 +/- 27.4 (jitter = 218.1) 7.485
3360 images/sec: 2100.2 +/- 25.6 (jitter = 173.0) 7.485
3460 images/sec: 2100.3 +/- 23.3 (jitter = 66.1) 7.501
3560 images/sec: 2100.4 +/- 24.8 (jitter = 190.7) 7.480
3660 images/sec: 2100.2 +/- 26.4 (jitter = 20.6) 7.493
3770 images/sec: 2100.4 +/- 24.3 (jitter = 16.4) 7.495
3870 images/sec: 2100.4 +/- 23.9 (jitter = 157.3) 7.498
3970 images/sec: 2100.0 +/- 22.1 (jitter = 52.3) 7.503
4070 images/sec: 2100.5 +/- 23.4 (jitter = 218.3) 7.509
4180 images/sec: 2100.3 +/- 22.4 (jitter = 157.3) 7.490
4280 images/sec: 2100.2 +/- 20.6 (jitter = 50.7) 7.510
4380 images/sec: 2100.6 +/- 21.7 (jitter = 195.2) 7.520
4480 images/sec: 2100.2 +/- 22.4 (jitter = 30.3) 7.508
4590 images/sec: 2100.8 +/- 21.2 (jitter = 22.3) 7.481
4690 images/sec: 2100.1 +/- 20.8 (jitter = 157.3) 7.489
4790 images/sec: 2100.7 +/- 19.7 (jitter = 35.1) 7.496
4890 images/sec: 2100.7 +/- 20.7 (jitter = 218.1) 7.471
49100 images/sec: 2100.2 +/- 20.2 (jitter = 30.3) 7.501
50----------------------------------------------------------------
51total images/sec: 8400.46
52----------------------------------------------------------------
53100 images/sec: 1520.1 +/- 19.9 (jitter = 166.6) 7.522
54----------------------------------------------------------------
55total images/sec: 8400.99
56----------------------------------------------------------------
57100 images/sec: 1517.6 +/- 18.6 (jitter = 52.3) 7.507
58----------------------------------------------------------------
59total images/sec: 8400.84
60----------------------------------------------------------------
61100 images/sec: 1517.9 +/- 19.6 (jitter = 219.0) 7.500
62----------------------------------------------------------------
63total images/sec: 8400.58
64----------------------------------------------------------------