不同打包方式下GRIB2文件加载速度对比:简单打包与JPEG压缩

目录

GRIB 2 格式文件支持使用不同方式保存要素场数据,可以使用二维数组的一维展开,也可以使用类似 JPEG、PNG 等图片格式对二维数据进行压缩。

本文介绍不同打包方式下从 GRIB 2 文件中加载要素场的速度。

打包方式

不同中心生成的 GRIB 2 数据使用不同的打包方式:

  • CMA 天气预报模式:JPEG2000 压缩 (grid_jpeg)
  • ECMWF 公开数据:简单打包,无压缩 (grid_simple)
  • NCEP GFS:复杂打包 (grid_complex_spatial_differencing)

本文测试 wgrib2 支持的部分打包方式,如下表所示:

wgrib2 nameeccodes packingType说明
jpeggrid_jpegJPEG2000 压缩
simplegrid_simple无压缩,打包缩放后的整数
ieeegrid_ieeeIEEE 格式 (每个数据点 4 字节)
complex1grid_complexcomplex packing
complex2grid_complex_spatial_differencingcomplex packing, pack increments (deltas)
complex3grid_complex_spatial_differencingcomplex packing, pack increments after linear extrapolation
aecgrid_ccsds使用 libaec 实现的 CCSDS 压缩

准备数据

使用 CMA-MESO V5.1 的等压面产品作为测试数据,原始文件使用 JPEG 方式压缩。

使用 wgrib2 -set_grib_type 命令将 GRIB 2 文件转为不同的打包方式,例如下面命令将文件转为 simple 打包方式:

wgrib2 -set_grib_type simple rmf.hgra.2022031000003.grb2 -grib_out rmf.hgra.2022031000003.grb2.simple

转换后的文件列表如下:

1.1G    rmf.hgra.2022031000003.grb2
1.3G    rmf.hgra.2022031000003.grb2.aec
1.6G    rmf.hgra.2022031000003.grb2.complex1
1.3G    rmf.hgra.2022031000003.grb2.complex2
1.3G    rmf.hgra.2022031000003.grb2.complex3
8.7G    rmf.hgra.2022031000003.grb2.ieee
3.6G    rmf.hgra.2022031000003.grb2.simple

测试

读取代码

从 GRIB 2 文件中加载层次类型为 isobaricInhPa 的所有温度场,使用两种方式:

  1. cfgrib
import cfgrib

file_path = "./rmf.hgra.2022031000003.grb2"
ds = cfgrib.open_dataset(
    file_path,
    backend_kwargs={
        'filter_by_keys': {'typeOfLevel': 'isobaricInhPa', 'shortName': 't'},
        'indexpath': ''
    }
)
ds.load()
  1. reki
file_path = "./rmf.hgra.2022031000003.grb2"
ds = load_field_from_file(
    file_path,
    parameter="t",
    level_type="isobaricInhPa",
    level="all"
)
ds.load()

注:cfgrib 的 open_dataset() 函数使用延迟加载方式,仅读取 GRIB2 消息头,不读取数据值,测试代码使用 ds.load() 载入数据值。 reki 的 load_field_from_file() 会一次性解码消息头和数据值,ds.load() 语句可以注释掉。

测试方法

在 CMA-PI HPC 上使用简单方法测试以上程序的运行时长,为了避免 import 阶段时长带来的差异,直接统计核心段的墙钟时间。 统计结果仅是 近似值,只用来对比不同打包方式的相对运行时长。

注意:以下方法得到的运行时长仅是部分代码运行的墙钟时间,不是该段代码运行的实际时间,也不是整个程序运行的时间。

import pandas as pd

start_time = pd.Timestamp.now()

# ... real code ...

end_time = pd.Timestamp.now()
print(end_time - start_time)

测试结果

不同打包方式下 cfgrib 和 reki 版本的载入时间如下:

打包方式cfgrib (s)reki (s)
jpeg2722
simple53
ieee139
aec53
complex153
complex253
complex353

简单打包方式比 JPEG 压缩方式加载速度快 5 倍以上。

进一步分析

不同文件仅打包方式不同,而打包方式与要素场数据值解码操作有关。 也就是上述代码运行时长与 eccodes.grib_get_double_array() 函数执行时间有关。 为了验证这一想法,对函数调用的运行时长进行进一步测试分析。

使用 Profile 工具分析代码运行时长,main() 函数和 ggrib_get_double_array() 函数运行总时长如下表所示,单位是毫秒 (ms):

打包方式mainget array
simple4254368
jpeg2270620805
ieee9873337
aec39161644
complex137401101
complex24108968
complex333821024

main() 函数中其他部分运行时长与 grib_get_double_array() 函数运行时长的关系如下图所示:

图 不同打包方式下核心段代码的运行时长

从上图可以看到,JPEG 压缩方式主要耗时都在数组解码,也就是 JPEG2000 解压缩操作。 简单打包方式与 JPEG 压缩方式运行时长的差异也基本来自于数组解码操作。

参考

reki 库是为 CMA 天气模式开发的数据准备 Python 开源工具库,提供检索要素场的便捷方法。

项目地址:https://github.com/nwpc-oper/reki

文档:https://reki.readthedocs.io/

reki库快速上手指南

相关文章:

GRIB笔记:使用cfgrib加载GRIB文件

GRIB笔记:cfgrib加载GRIB2要素场速度测试

一篇对比文件大小的微信公众号文章:《一份GRIB与NetCDF的文件体积对比报告