Feat: Overlap movie output and cut per-frame fast-mode work
- Gather the union of every movie frame's all-sky tiles once and read them in bounded batches, replacing the per-frame prefetch scan and log. - Fuse the fast supersampled-buffer clear into the FFTW pack pass so a resolved frame starts clean with no serial memset. - Split parallel HDR->RGB8 tone mapping from PNG encoding. - Add a bounded single-producer/single-writer movie output queue used by both observer movies and multi-frame imported lens maps, with writer timing and error propagation. - Add --png-compression-level and --movie-output-workers shared|reserve-one. - Add --fast-fftw-plan estimate|measure|wisdom|wisdom-update with strict wisdom identity sidecars. - Add staged movie timing, regression tests, and docs.
This commit is contained in:
1 parent
a510fec23e
commit
04611e3e5a
20 files changed
+2282
-212
No files matched your search
@@ -24,42 +24,83 @@ static int write_tile(const char *directory, int ra_index, int dec_index,
|
||||
return result ? -1 : 0;
|
||||
}
|
||||
|
||||
static int tile_state(const StarCatalog *catalog, int ra, int dec) {
|
||||
return catalog->tiles[(size_t)dec * CATALOG_ALL_SKY_RA_TILES + ra].state;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
char directory[] = "/tmp/catalog_prefetch_XXXXXX";
|
||||
char path[4096];
|
||||
StarCatalog catalog = {0};
|
||||
unsigned char requested[CATALOG_ALL_SKY_TILE_COUNT] = {0};
|
||||
CatalogPrefetchStats first = {0}, second = {0};
|
||||
StarCatalog batched = {0};
|
||||
int result = 1;
|
||||
if (mkdtemp(directory) == NULL || write_tile(directory, 0, 90, 0.0) ||
|
||||
write_tile(directory, 1, 90, 1.0) ||
|
||||
catalog_load_all_sky(&catalog, directory))
|
||||
goto done;
|
||||
requested[90 * CATALOG_ALL_SKY_RA_TILES] = 1;
|
||||
requested[90 * CATALOG_ALL_SKY_RA_TILES + 1] = 1;
|
||||
requested[90 * CATALOG_ALL_SKY_RA_TILES + 2] = 1; /* Missing on purpose. */
|
||||
if (catalog_prefetch_marked_tiles(&catalog, requested, 4, &first) ||
|
||||
first.requested_tiles != 3 || first.newly_loaded_tiles != 2 ||
|
||||
first.unavailable_tiles != 1 || first.newly_loaded_stars != 2 ||
|
||||
catalog.count != 2 ||
|
||||
catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES].state != 1 ||
|
||||
catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES + 1].state != 1 ||
|
||||
catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES + 2].state != -1) {
|
||||
fputs("parallel catalog prefetch regression failed\n", stderr);
|
||||
|
||||
/* Two overlapping sets: A = {0,1}, B = {1,2}; the union is {0,1,2}, and
|
||||
* tile 2 is intentionally missing from disk. */
|
||||
CatalogTileSet set_a;
|
||||
CatalogTileSet set_b;
|
||||
CatalogTileSet union_set;
|
||||
catalog_tile_set_clear(&set_a);
|
||||
catalog_tile_set_clear(&set_b);
|
||||
catalog_tile_set_clear(&union_set);
|
||||
set_a.requested[90 * CATALOG_ALL_SKY_RA_TILES] = 1;
|
||||
set_a.requested[90 * CATALOG_ALL_SKY_RA_TILES + 1] = 1;
|
||||
set_b.requested[90 * CATALOG_ALL_SKY_RA_TILES + 1] = 1;
|
||||
set_b.requested[90 * CATALOG_ALL_SKY_RA_TILES + 2] = 1;
|
||||
for (int ra = 0; ra < 3; ++ra)
|
||||
union_set.requested[90 * CATALOG_ALL_SKY_RA_TILES + ra] =
|
||||
set_a.requested[90 * CATALOG_ALL_SKY_RA_TILES + ra] ||
|
||||
set_b.requested[90 * CATALOG_ALL_SKY_RA_TILES + ra];
|
||||
if (catalog_tile_set_count(&set_a) != 2 ||
|
||||
catalog_tile_set_count(&set_b) != 2 ||
|
||||
catalog_tile_set_count(&union_set) != 3) {
|
||||
fputs("catalog tile-set union regression failed\n", stderr);
|
||||
goto done;
|
||||
}
|
||||
Star *first_tile = catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES].stars;
|
||||
if (catalog_prefetch_marked_tiles(&catalog, requested, 2, &second) ||
|
||||
|
||||
CatalogPrefetchStats first = {0};
|
||||
if (catalog_prefetch_tile_set(&catalog, &union_set, 4,
|
||||
CATALOG_PREFETCH_DEFAULT_BATCH_TILES, &first) ||
|
||||
first.requested_tiles != 3 || first.newly_loaded_tiles != 2 ||
|
||||
first.unavailable_tiles != 1 || first.newly_loaded_stars != 2 ||
|
||||
catalog.count != 2 || tile_state(&catalog, 0, 90) != 1 ||
|
||||
tile_state(&catalog, 1, 90) != 1 || tile_state(&catalog, 2, 90) != -1) {
|
||||
fputs("parallel catalog union prefetch regression failed\n", stderr);
|
||||
goto done;
|
||||
}
|
||||
Star *first_tile =
|
||||
catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES].stars;
|
||||
|
||||
/* Re-prefetching the same union must read nothing and must not re-mark the
|
||||
* unavailable tile. */
|
||||
CatalogPrefetchStats second = {0};
|
||||
if (catalog_prefetch_tile_set(&catalog, &union_set, 2,
|
||||
CATALOG_PREFETCH_DEFAULT_BATCH_TILES, &second) ||
|
||||
second.requested_tiles != 3 || second.newly_loaded_tiles != 0 ||
|
||||
second.unavailable_tiles != 0 || second.newly_loaded_stars != 0 ||
|
||||
catalog.count != 2 ||
|
||||
catalog.tiles[90 * CATALOG_ALL_SKY_RA_TILES].stars != first_tile) {
|
||||
fputs("catalog prefetch cache reuse regression failed\n", stderr);
|
||||
fputs("catalog union prefetch cache reuse regression failed\n", stderr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* A batch size of one must reach the same final cache as the default. */
|
||||
if (catalog_load_all_sky(&batched, directory) ||
|
||||
catalog_prefetch_tile_set(&batched, &union_set, 4, 1, NULL) ||
|
||||
batched.count != catalog.count ||
|
||||
tile_state(&batched, 0, 90) != 1 || tile_state(&batched, 1, 90) != 1 ||
|
||||
tile_state(&batched, 2, 90) != -1) {
|
||||
fputs("catalog single-tile batching regression failed\n", stderr);
|
||||
goto done;
|
||||
}
|
||||
result = 0;
|
||||
done:
|
||||
catalog_destroy(&catalog);
|
||||
catalog_destroy(&batched);
|
||||
for (int ra = 0; ra < 3; ++ra) {
|
||||
const int written = snprintf(path, sizeof path, "%s/tile_ra%03d_dec090.csv",
|
||||
directory, ra);
|
||||
|
||||
Reference in new issue
Block a user