Phase 19: measure graph scaling and guard capacity and contention behavior
This commit is contained in:
parent
1369e4d463
commit
6b85f28add
9 changed files with 639 additions and 3 deletions
60
tests/integration/benchmark_graph.c
Normal file
60
tests/integration/benchmark_graph.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "xtc/xtc_engine.h"
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
static double now(void)
|
||||
{ struct timespec t; if (clock_gettime(CLOCK_MONOTONIC,&t)) abort(); return (double)t.tv_sec+(double)t.tv_nsec/1e9; }
|
||||
static int compare(const void *a,const void *b)
|
||||
{ double x = *(const double *)a,y = *(const double *)b; return x < y ? -1 : x > y; }
|
||||
static size_t number(const char *s,size_t maximum)
|
||||
{
|
||||
char *end; unsigned long n;
|
||||
errno = 0; n = strtoul(s,&end,10);
|
||||
if (errno || !s[0] || *end || n < 1 || n > maximum) return 0;
|
||||
return (size_t)n;
|
||||
}
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
size_t nodes,channels,rate,frames,blocks,i,j,id = 0,previous = 0;
|
||||
xtc_graph *g = NULL; xtc_plan *p = NULL;
|
||||
float *in = NULL,*left = NULL,*right = NULL;
|
||||
double *times = NULL,begin,compile,total = 0;
|
||||
int status = 1;
|
||||
if (argc != 6) return 1;
|
||||
nodes = number(argv[1],256); channels = number(argv[2],2); rate = number(argv[3],768000);
|
||||
frames = number(argv[4],65536); blocks = number(argv[5],100000);
|
||||
if (nodes < 2 || !channels || !rate || !frames || !blocks) return 1;
|
||||
in = calloc(frames,sizeof(float)); left = calloc(frames,sizeof(float)); right = calloc(frames,sizeof(float));
|
||||
times = calloc(blocks,sizeof(double));
|
||||
if (!in || !left || !right || !times || xtc_graph_create(nodes,&g) != XTC_OK) goto done;
|
||||
for (i = 0; i < nodes; ++i) {
|
||||
xtc_result r = i+1 == nodes ? xtc_graph_add_output(g,&id) :
|
||||
i+2 == nodes ? xtc_graph_add_meter(g,&id) : xtc_graph_add_gain(g,.999f,&id);
|
||||
if (r != XTC_OK || (i && xtc_graph_connect(g,previous,id) != XTC_OK)) goto done;
|
||||
previous = id;
|
||||
}
|
||||
begin = now();
|
||||
if (xtc_graph_compile(g,(double)rate,frames,&p) != XTC_OK) goto done;
|
||||
compile = now()-begin;
|
||||
for (i = 0; i < frames; ++i) in[i] = (float)sin((double)i*.1)*.1f;
|
||||
/* Warm caches outside the sample, then measure only the process call. */
|
||||
for (i = 0; i < 20; ++i) if (xtc_plan_process_stereo(p,in,NULL,NULL,NULL,NULL,left,channels == 2 ? right : NULL,frames) != XTC_OK) goto done;
|
||||
for (i = 0; i < blocks; ++i) {
|
||||
begin = now();
|
||||
if (xtc_plan_process_stereo(p,in,NULL,NULL,NULL,NULL,left,channels == 2 ? right : NULL,frames) != XTC_OK) goto done;
|
||||
times[i] = now()-begin; total += times[i];
|
||||
for (j = 0; j < frames; ++j) if (!isfinite(left[j]) || (channels == 2 && !isfinite(right[j]))) goto done;
|
||||
}
|
||||
qsort(times,blocks,sizeof(double),compare);
|
||||
printf("{\"nodes\":%zu,\"channels\":%zu,\"rate\":%zu,\"frames\":%zu,\"blocks\":%zu,"
|
||||
"\"compile_ms\":%.6f,\"mean_us\":%.6f,\"p99_us\":%.6f,\"max_us\":%.6f,\"deadline_us\":%.6f,"
|
||||
"\"load\":%.6f,\"graph_buffer_bytes\":%zu}\n",nodes,channels,rate,frames,blocks,compile*1e3,total/(double)blocks*1e6,
|
||||
times[blocks*99/100]*1e6,times[blocks-1]*1e6,(double)frames/(double)rate*1e6,
|
||||
total/(double)blocks/((double)frames/(double)rate),nodes*frames*2*sizeof(float));
|
||||
status = 0;
|
||||
done:
|
||||
free(in); free(left); free(right); free(times); xtc_plan_destroy(p); xtc_graph_destroy(g); return status;
|
||||
}
|
||||
42
tests/integration/test_scale.c
Normal file
42
tests/integration/test_scale.c
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#include "xtc/xtc_midi.h"
|
||||
#include "xtc/xtc_audio.h"
|
||||
#include "xtc/xtc_mixer.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
int main(void)
|
||||
{
|
||||
xtc_project *p = NULL; xtc_midi_plan *midi = NULL; xtc_audio_plan *audio = NULL;
|
||||
xtc_graph *graph = NULL; xtc_plan *plan = NULL;
|
||||
uint64_t tracks[XTC_PROJECT_MAX_TRACKS],clips[XTC_PROJECT_MAX_CLIPS],id;
|
||||
size_t i,j,previous = 0,node; float left[31],right[31],out[31],other[31];
|
||||
assert(xtc_project_create(&p) == XTC_OK);
|
||||
for (i = 0; i < XTC_PROJECT_MAX_TRACKS; ++i) assert(xtc_project_add_track(p,"Scale",tracks+i) == XTC_OK);
|
||||
assert(xtc_project_add_track(p,"Excess",&id) == XTC_ERR_CAPACITY);
|
||||
for (i = 0; i < XTC_PROJECT_MAX_CLIPS; ++i) assert(xtc_project_add_midi_clip(p,tracks[i%64],i*4,4,clips+i) == XTC_OK);
|
||||
assert(xtc_project_add_midi_clip(p,tracks[0],0,4,&id) == XTC_ERR_CAPACITY);
|
||||
for (i = 0; i < XTC_PROJECT_MAX_NOTES; ++i) assert(xtc_project_add_note(p,clips[i%1024],i/1024,1,60,100,0,&id) == XTC_OK);
|
||||
assert(xtc_project_add_note(p,clips[0],0,1,60,100,0,&id) == XTC_ERR_CAPACITY);
|
||||
for (i = 0; i < XTC_MAX_AUTOMATION_POINTS; ++i) {
|
||||
xtc_automation_point a = {tracks[i%64],i/64,XTC_AUTOMATION_GAIN,.1f};
|
||||
assert(xtc_project_set_automation(p,&a) == XTC_OK);
|
||||
}
|
||||
{ xtc_automation_point a = {tracks[0],1000,XTC_AUTOMATION_GAIN,1}; assert(xtc_project_set_automation(p,&a) == XTC_ERR_CAPACITY); }
|
||||
assert(xtc_graph_create(256,&graph) == XTC_OK && xtc_graph_add_instrument(graph,&previous) == XTC_OK);
|
||||
for (i = 1; i < 256; ++i) {
|
||||
assert((i == 255 ? xtc_graph_add_output(graph,&node) : xtc_graph_add_meter(graph,&node)) == XTC_OK);
|
||||
assert(xtc_graph_connect(graph,previous,node) == XTC_OK); previous = node;
|
||||
}
|
||||
assert(xtc_graph_add_gain(graph,1,&node) == XTC_ERR_CAPACITY);
|
||||
assert(xtc_graph_compile(graph,96000,31,&plan) == XTC_OK);
|
||||
assert(xtc_midi_plan_create(p,96000,&midi) == XTC_OK && xtc_audio_plan_create(p,96000,&audio) == XTC_OK);
|
||||
for (i = 0; i < 100; ++i) {
|
||||
assert(xtc_midi_plan_render_stereo(midi,i*31,NULL,0,left,right,31) == XTC_OK);
|
||||
assert(xtc_plan_process_stereo(plan,NULL,NULL,NULL,left,right,out,other,31) == XTC_OK);
|
||||
for (j = 0; j < 31; ++j) assert(isfinite(out[j]) && out[j] == other[j]);
|
||||
}
|
||||
xtc_audio_plan_destroy(audio); xtc_midi_plan_destroy(midi); xtc_plan_destroy(plan);
|
||||
xtc_graph_destroy(graph); xtc_project_destroy(p);
|
||||
puts("64 tracks, 1024 clips/points, 4096 notes, 256 metered nodes and capacity failures passed.");
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue