#include #include #include #include #include #include "bench.hfa" // int Actors = 40000, Set = 100, Rounds = 100, Processors = 1, Batch = 1, BufSize = 10; // default values int ActorsPerQueue = 32, Set = 32, Rounds = 100, Processors = 1, Batch = 100, BufSize = 10; // other defaults for test to run in reasonable time struct filler { inline actor; }; void ?{}( filler & this ) with(this) { ((actor &)this){}; } static int ids = 0; struct d_actor { inline actor; int gstart, id, rounds, recs, sends; }; void ?{}( d_actor & this, int idx ) with(this) { ((actor &)this){}; id = idx; gstart = id / Set * Set; // remember group-start index rounds = Set * Rounds; // send at least one message to each group member recs = 0; sends = 0; } struct d_msg { inline message; } shared_msg; struct start_msg { inline message; } start_send; d_actor ** actor_arr; allocation receive( d_actor & this, start_msg & msg ) with( this ) { for ( i; Set ) { *actor_arr[i + gstart] | shared_msg; } return Nodelete; } allocation receive( d_actor & this, d_msg & msg ) with( this ) { if ( recs == rounds ) return Delete; if ( recs % Batch == 0 ) { for ( i; Batch ) { *actor_arr[gstart + sends % Set] | shared_msg; sends += 1; } } recs += 1; return Nodelete; } allocation receive( filler & this, d_msg & msg ) { return Delete; } int main( int argc, char * argv[] ) { switch ( argc ) { case 7: if ( strcmp( argv[6], "d" ) != 0 ) { // default ? BufSize = atoi( argv[6] ); if ( BufSize < 0 ) goto Usage; } // if case 6: if ( strcmp( argv[5], "d" ) != 0 ) { // default ? Batch = atoi( argv[5] ); if ( Batch < 1 ) goto Usage; } // if case 5: if ( strcmp( argv[4], "d" ) != 0 ) { // default ? Processors = atoi( argv[4] ); if ( Processors < 1 ) goto Usage; } // if case 4: if ( strcmp( argv[3], "d" ) != 0 ) { // default ? Rounds = atoi( argv[3] ); if ( Rounds < 1 ) goto Usage; } // if case 3: if ( strcmp( argv[2], "d" ) != 0 ) { // default ? Set = atoi( argv[2] ); if ( Set < 1 ) goto Usage; } // if case 2: if ( strcmp( argv[1], "d" ) != 0 ) { // default ? ActorsPerQueue = atoi( argv[1] ); if ( ActorsPerQueue < 1 ) goto Usage; } // if case 1: // use defaults break; default: Usage: sout | "Usage: " | argv[0] | " [ ActorsPerQueue (> 0) | 'd' (default " | ActorsPerQueue | ") ] [ set (> 0) | 'd' (default " | Set | ") ] [ rounds (> 0) | 'd' (default " | Rounds | ") ] [ processors (> 0) | 'd' (default " | Processors | ") ] [ batch (> 0) | 'd' (default " | Batch | ") ] [ buffer size (>= 0) | 'd' (default " | BufSize | ") ]" ; exit( EXIT_FAILURE ); } // switch unsigned int qpw = 512; // queues per worker executor e{ Processors, Processors, Processors == 1 ? 1 : Processors * qpw, true }; // printf("starting\n"); start_actor_system( e ); // printf("started\n"); #ifndef MULTI int Actors = ActorsPerQueue * qpw; int FillActors = ActorsPerQueue * qpw * (Processors - 1); #else int extra = Processors % 2; int ActorProcs = (Processors / 2 + extra); int Actors = ActorsPerQueue * qpw * ActorProcs; int FillActors = ActorsPerQueue * qpw * (Processors/2); #endif int fill_offset = (Processors - 1) * qpw; int AllocFill = FillActors; if ( FillActors == 0 ) AllocFill = 1; d_actor ** actors; // array needs to be on the heap since it can be very large actors = aalloc( Actors ); actor_arr = actors; filler ** filler_actors; // array needs to be on the heap since it can be very large filler_actors = aalloc( AllocFill ); int actor_count = 0; int fill_count = 0; int idx; for ( i; ActorsPerQueue ) { for ( j; Processors ) { for ( k; qpw ) { #ifndef MULTI if ( j == 0 ) #else if ( j % 2 == 0 ) #endif { #ifndef MULTI idx = k * ActorsPerQueue + i; #else idx = (j / 2) * qpw * ActorsPerQueue + k * ActorsPerQueue + i; // set all on one queue #endif (*(actors[ idx ] = alloc())){ idx }; } else { (*(filler_actors[ fill_count ] = alloc())){}; fill_count++; } } } } uint64_t start_time = bench_time(); #ifndef MULTI for ( i; qpw ) *actors[i * ActorsPerQueue] | start_send; #else for ( i; qpw * ActorProcs ) { *actors[i * ActorsPerQueue] | start_send; } #endif for ( i; FillActors ) *filler_actors[i] | shared_msg; stop_actor_system(); uint64_t end_time = bench_time(); printf("%.2f\n", ((double)(end_time - start_time))*((double)1e-9) ); adelete( filler_actors ); adelete( actors ); return 0; }