Spacetime: free analytic render worker count

This commit is contained in:
wyj committed 2026-08-28 17:20:00 -04:00
1 parent 9b23f3717e
commit 5fd8e3819d
7 files changed
+38 -16

No files matched your search

+12 -9
View File
@@ -8,9 +8,9 @@
#include <stdint.h>
#include <stdlib.h>
/* Private HDR buffers make splatting independent across workers. This is an
* allocation cap, not a rendering parameter: callers transparently fall back
* to the serial implementation when the frame is too large for two buffers. */
/* Numerical metric backends may reserve substantial memory for slabs and
* thread-local evaluators, so they retain this private-HDR allocation budget.
* Analytic backends deliberately use all OpenMP render workers instead. */
#define FRAME_SPLAT_MAX_PRIVATE_HDR_BYTES ((size_t)512 * 1024 * 1024)
static const double pi = 3.14159265358979323846;
@@ -290,6 +290,7 @@ size_t frame_splat_catalog(const FrameLensMesh *mesh,
int height, double exposure,
const PointSpreadFunction *psf,
const PsfKernelCache *psf_cache,
int limit_workers_by_memory,
int catalog_load_workers,
CatalogPrefetchStats *prefetch_stats,
PsfSplatStats *psf_stats,
@@ -315,8 +316,7 @@ size_t frame_splat_catalog(const FrameLensMesh *mesh,
mesh->triangle_count);
const size_t pixel_count = (size_t)width * height * 3;
if (pixel_count > SIZE_MAX / sizeof(double) ||
pixel_count * sizeof(double) > FRAME_SPLAT_MAX_PRIVATE_HDR_BYTES / 2)
if (pixel_count > SIZE_MAX / sizeof(double))
{
size_t fallbacks = 0;
const size_t images = splat_catalog_triangles(mesh, catalog, hdr, width, height,
@@ -324,12 +324,15 @@ size_t frame_splat_catalog(const FrameLensMesh *mesh,
mesh->triangle_count, &fallbacks);
if (psf_stats != NULL) *psf_stats = (PsfSplatStats){images - fallbacks, fallbacks};
return images;
}
}
const size_t buffer_bytes = pixel_count * sizeof(double);
size_t worker_count = FRAME_SPLAT_MAX_PRIVATE_HDR_BYTES / buffer_bytes;
const int max_threads = omp_get_max_threads();
if (worker_count > (size_t)max_threads)
worker_count = (size_t)max_threads;
size_t worker_count = max_threads > 0 ? (size_t)max_threads : 0;
if (limit_workers_by_memory) {
worker_count = FRAME_SPLAT_MAX_PRIVATE_HDR_BYTES / buffer_bytes;
if (worker_count > (size_t)max_threads)
worker_count = (size_t)max_threads;
}
if (worker_count < 2 || worker_count > INT_MAX)
{
size_t fallbacks = 0;
+1
View File
@@ -56,6 +56,7 @@ size_t frame_splat_catalog(const FrameLensMesh *mesh,
int height, double exposure,
const PointSpreadFunction *psf,
const PsfKernelCache *psf_cache,
int limit_workers_by_memory,
int catalog_load_workers,
CatalogPrefetchStats *prefetch_stats,
PsfSplatStats *psf_stats,
+5 -2
View File
@@ -305,7 +305,8 @@ static int render_observer_frame(const Settings *s, StarCatalog *catalog,
.all_sky_catalog = catalog->kind == STAR_CATALOG_ALL_SKY};
size_t images = frame_splat_catalog(
&mesh, catalog, hdr, s->width, s->height, s->exposure, &s->psf,
&s->psf_cache, s->catalog_load_workers, &prefetch, &psf_stats,
&s->psf_cache, spacetime_limits_render_workers_by_memory(spacetime),
s->catalog_load_workers, &prefetch, &psf_stats,
&(FrameSplatProgress){report_splat_progress, &progress});
if (s->draw_mesh)
frame_draw_mesh(&mesh, hdr, s->width, s->height, 0.5, 0.5);
@@ -434,7 +435,9 @@ static int render_movie(const Settings *s, StarCatalog *catalog,
.all_sky_catalog = catalog->kind == STAR_CATALOG_ALL_SKY};
const size_t images = frame_splat_catalog(
&movie.frames[i].mesh, catalog, hdr, s->width, s->height, s->exposure,
&s->psf, &s->psf_cache, s->catalog_load_workers, &prefetch, &psf_stats,
&s->psf, &s->psf_cache,
spacetime_limits_render_workers_by_memory(spacetime),
s->catalog_load_workers, &prefetch, &psf_stats,
&(FrameSplatProgress){report_splat_progress, &progress});
if (s->draw_mesh)
frame_draw_mesh(&movie.frames[i].mesh, hdr, s->width, s->height, 0.5, 0.5);
+5
View File
@@ -38,6 +38,10 @@ typedef struct {
MetricData *metric);
SpacetimeRayStatus (*classify_slab)(const MetricSlab *slab, double t,
const double x[3]);
/* Analytic backends have negligible per-ray metric state. A numerical
* backend must opt in once its metric slabs and evaluator workspaces need
* to reserve memory alongside the private HDR render buffers. */
int limit_render_workers_by_memory;
void (*destroy)(SpacetimeSource *source);
} SpacetimeOps;
@@ -65,5 +69,6 @@ int spacetime_slab_eval(const MetricSlab *slab, double t, const double x[3],
MetricData *metric);
SpacetimeRayStatus spacetime_slab_classify(const MetricSlab *slab, double t,
const double x[3]);
int spacetime_limits_render_workers_by_memory(const SpacetimeSource *source);
#endif
+5
View File
@@ -63,3 +63,8 @@ SpacetimeRayStatus spacetime_slab_classify(const MetricSlab *slab, double t,
return slab->source->ops->classify_slab(slab, t, x);
return spacetime_classify(slab->source, t, x);
}
int spacetime_limits_render_workers_by_memory(const SpacetimeSource *source) {
return source != NULL && source->ops != NULL &&
source->ops->limit_render_workers_by_memory;
}