magistraleinformaticanetworking:spm:spm1213_c_ff_false_sharing_fs3
- fs3.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <ff/farm.hpp>
using namespace ff;
using namespace std;
typedef struct __task {
int id;
int start;
int end;
} TASK;
typedef union __res {
float x;
float pad[16];
} RES;
int n;
float ** mat;
RES * vec;
class Emitter : public ff_node {
private:
int chunk;
public:
Emitter(int chunk):chunk(chunk) { }
void * svc(void * t) {
int given = 0;
int id = 0;
while(given < n) {
TASK * otask = new TASK();
otask->start = given;
otask->end = (given+chunk >= n ? n : given+chunk);
otask->id = id++;
given = otask->end;
// cout << "Emitting task " << otask->start << " to " << otask->end << endl;
ff_send_out((void*) otask);
}
return(EOS);
}
};
class Worker : public ff_node {
private:
int wid;
public:
Worker(int i):wid(i) {}
void * svc(void * t) {
TASK * task = (TASK *) t;
// cout << "Computing " << task->start << " to " << task->end << endl;
struct timespec t0, t1;
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t0);
for(int i=task->start; i<task->end; i++) {
for(int j=0; j<n; j++)
vec[wid].x += mat[i][j];
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t1);
// cout << "Worker got " << t1.tv_nsec - t0.tv_nsec << " (" << t1.tv_sec - t0.tv_sec << ")" << endl;
return (t);
}
};
int main(int argc, char * argv[]) {
if(argc!=5) {
cout << "Usage is:\n" << argv[0] << " n m chunk nw" << endl;
return(0);
}
n = atoi(argv[1]);
int m = atoi(argv[2]);
int ck = atoi(argv[3]);
int nw = atoi(argv[4]);
cout << "Float is " << sizeof(float) << " bytes " << endl;
// cout << "Init 1" << endl;
mat = new float*[n];
for(int i=0; i<n; i++)
mat[i] = new float[n];
// cout << "Init 2" << endl;
srand(123);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mat[i][j] = ((float) rand()) / ((float) RAND_MAX);
// cout << "Init 3" << endl;
vec = new RES[nw];
for(int i=0; i<nw; i++)
vec[i].x = 0.0;
// cout << "Program " << endl;
ff_farm<> farm;
vector<ff_node *> w;
for(int i=0; i<nw; i++)
w.push_back(new Worker(i));
farm.add_workers(w);
farm.add_emitter(new Emitter(ck));
// cout << "Start" << endl;
farm.run_and_wait_end();
// cout << "Finalize" << endl;
// now find the sum of the partial results
float sum = 0.0;
for(int i=0; i<nw; i++)
sum += vec[i].x;
farm.ffStats(cerr);
// cout << "total sum is " << sum << " in " << farm.ffTime() << " msec" << endl;
cout << argv[0] << " computed in " << farm.ffTime() << " msec with " << nw << " workers (n= " << n << " chunk= " << ck << " )" << endl;
}
magistraleinformaticanetworking/spm/spm1213_c_ff_false_sharing_fs3.txt · Ultima modifica: 16/04/2013 alle 16:08 (11 anni fa) da Marco Danelutto