an example of parallel calculation of metrics

Jay Norwood via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Oct 1 08:56:50 PDT 2015


On Thursday, 1 October 2015 at 07:03:40 UTC, Ali Çehreli wrote:
> Looks like a bug. Workaround: Get rid of member names

Thanks.  My particular use case, working with metric expressions, 
is easier to understand if I use the names.  I converted the use 
of Tuple to struct to see if I could get an easier error msg. 
Turns out the use of struct also results in much cleaner writeln 
text.

Still has the compile error, though.

import std.algorithm, std.parallelism, std.range;
import std.stdio;
import std.datetime;
import std.typecons;
import std.meta;

// define some input measurement sample tuples and output metric 
tuples
struct TR {double per_sec; double per_cycle; long raw;}
struct TI {long proc_cyc;  long DATA_RD; long DATA_WR; long 
INST_FETCH; long L1I_MISS; long L1I_HIT; long L1D_HIT; long 
L1D_MISS;}
struct TO { TR L1_MISS; TR L1_HIT; TR DATA_ACC; TR ALL_ACC;}
const double CYC_PER_SEC = 1_600_000_000;

// various metric definitions
// using Tuples with defined names for each member, and use the 
names here in the metrics.
TR met_l1_miss ( ref TI m){ TR rv; with(rv) with(m) { raw = 
L1I_MISS+L1D_MISS; per_cycle = cast(double)raw/proc_cyc; per_sec 
= per_cycle*CYC_PER_SEC;} return rv; }
TR met_l1_hit ( ref TI m){ TR rv; with(rv) with(m) { raw = 
L1I_HIT+L1D_HIT; per_cycle = cast(double)raw/proc_cyc; per_sec = 
per_cycle*CYC_PER_SEC;} return rv; }
TR met_data_acc ( ref TI m){ TR rv; with(rv) with(m) { raw = 
DATA_RD+DATA_WR; per_cycle = cast(double)raw/proc_cyc; per_sec = 
per_cycle*CYC_PER_SEC;} return rv; }
TR met_all_acc( ref TI m){ TR rv; with(rv) with(m) { raw = 
DATA_RD+DATA_WR+INST_FETCH; per_cycle = cast(double)raw/proc_cyc; 
per_sec = per_cycle*CYC_PER_SEC;} return rv; }

// a convenience to use all the metrics above as a list
alias Metrics = 
AliasSeq!(met_l1_miss,met_l1_hit,met_data_acc,met_all_acc);

void main(string[] argv)
{
	auto samples = iota(1_00);
	auto meas = new TI[samples.length];
	auto results = new TO[samples.length];

	// Initialize some values for the measured samples
	foreach(i, ref m; meas){
		with(m){ proc_cyc = 1_000_000+i*2; DATA_RD = 1000+i; DATA_WR= 
2000+i; INST_FETCH=proc_cyc/2;
		        L1I_HIT= INST_FETCH-100; L1I_MISS=100;
				L1D_HIT= DATA_RD+DATA_WR - 200; L1D_MISS=200;}
	}

	std.datetime.StopWatch sw;
	sw.start();

     ref TI getTerm(int i)
     {
         return meas[i];
     }

	// compute the metric results for the above measured sample 
values in parallel
	taskPool.amap!(Metrics)(std.algorithm.map!getTerm(samples),results);

	TR rv1 = met_l1_miss( meas[0]);
	TR rv2 = met_l1_hit( meas[0]);
	TR rv3 = met_data_acc( meas[0]);
	TR rv4 = met_all_acc( meas[0]);

	// how long did this take
	long exec_ms = sw.peek().msecs;
	writeln("measurements:", meas[0]);
	writeln("rv1:", rv1);
	writeln("rv2:", rv2);
	writeln("rv3:", rv3);
	writeln("rv4:", rv4);
	writeln("results:", results[1]);
	writeln("time:", exec_ms);

}




More information about the Digitalmars-d-learn mailing list