|
NEP 2.7.0
NetCDF Extension Pack
|
Demonstrates how Zstandard compression levels and the shuffle filter affect NetCDF-4 compression ratio and I/O throughput. More...
#include <netcdf.h>#include <netcdf_filter.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/time.h>Macros | |
| #define | NZ 500 |
| #define | NY 180 |
| #define | NX 360 |
| #define | TMP_FILE "zstandard_tmp.nc" |
| #define | CHUNK_Z 10 |
| #define | CHUNK_Y 45 |
| #define | CHUNK_X 90 |
| #define | NVALS ((size_t)NZ * NY * NX) |
| #define | UNCOMPRESSED_BYTES ((double)NVALS * sizeof(float)) |
| #define | ERRCODE 2 |
| #define | ERR(e) {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} |
| #define | NLEVELS (int)(sizeof(LEVELS) / sizeof(LEVELS[0])) |
Functions | |
| static double | get_time (void) |
| Return current wall-clock time in seconds. | |
| static int | run_one (float *data, int level, int shuffle) |
| Run one zstd/shuffle combination and print a CSV row. | |
| int | main (void) |
| Main entry point. | |
Variables | |
| static const int | LEVELS [] = {-7, -3, -1, 0, 1, 3, 6, 9, 12, 15, 19, 22} |
Demonstrates how Zstandard compression levels and the shuffle filter affect NetCDF-4 compression ratio and I/O throughput.
NetCDF-4/HDF5 supports Zstandard (zstd) compression via nc_def_var_zstandard(). Unlike zlib deflate (levels 0–9), zstd supports a much wider range: negative levels (-7 to -1) trade compression ratio for extreme write speed, level 1 is the fast default, and levels up to 22 push toward maximum compression at increasing CPU cost.
The shuffle filter (shuffle = 1) reorders bytes before compression: for IEEE 754 floating-point data the most-significant bytes of adjacent values are grouped together, which typically increases the compression ratio by 3–5× at little additional cost. Because nc_def_var_zstandard() does not accept a shuffle parameter directly, shuffle is enabled by calling nc_def_var_deflate(ncid, varid, 1, 0, 0) (shuffle only, no deflate) before nc_def_var_zstandard().
This program iterates a representative subset of 12 levels {-7, -3, -1, 0, 1, 3, 6, 9, 12, 15, 19, 22} × shuffle {off, on} (44 combinations total) over a 500×180×360 NC_FLOAT temperature dataset (~129 MB uncompressed) and reports:
Output: CSV printed to stdout with columns:
Typical workflow:
Learning Objectives:
Key Concepts:
Prerequisites:
Related Examples:
Key API functions:
| #define CHUNK_X 90 |
| #define CHUNK_Y 45 |
| #define CHUNK_Z 10 |
Chunk shape: matches all v1.10.0 performance examples for consistency.
| #define ERR | ( | e | ) | {printf("Error: %s\n", nc_strerror(e)); exit(ERRCODE);} |
| #define ERRCODE 2 |
| #define NX 360 |
Longitude dimension: 360 degrees.
| #define NY 180 |
Latitude dimension: 180 degrees.
| #define NZ 500 |
Time dimension: 500 time steps.
| #define TMP_FILE "zstandard_tmp.nc" |
Temporary NetCDF file created and removed for each measurement.
| #define UNCOMPRESSED_BYTES ((double)NVALS * sizeof(float)) |
Uncompressed size in bytes.
|
static |
Return current wall-clock time in seconds.
| int main | ( | void | ) |
Main entry point.
Allocates a 500×180×360 NC_FLOAT buffer with synthetic temperature data, then iterates 12 representative zstd levels × shuffle {0, 1} (44 rows total), printing one CSV row per combination.
|
static |
Run one zstd/shuffle combination and print a CSV row.
Creates zstandard_tmp.nc with the given zstd level and shuffle setting, writes a 500×180×360 NC_FLOAT temperature variable, stats the file to obtain the compressed size, reads the variable back, then removes the file.
When shuffle is 1, nc_def_var_deflate() is called with shuffle=1 and deflate=0 to activate the byte-shuffle filter without zlib compression; nc_def_var_zstandard() is then called to add zstd on top.
| data | Pre-allocated buffer of NVALS floats (synthetic data). |
| level | Zstandard compression level (-7 to 22). |
| shuffle | 1 to enable the shuffle filter, 0 to disable. |
|
static |
Representative zstd levels covering the full range -7 to 22.