Strumenti Utente

Strumenti Sito


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 (6 anni fa) da Marco Danelutto