Next: BM-4: the NAS Up: The Demo Examples. Previous: BM-2: A Fast

BM-3: The NAS Embarrassingly Parallel Bechmark

The NAS benchmark suite was designed to test the suitability of massively parallel systems for the needs of NASA Ames Research. Of the nine codes in the suite, four have been translated to pC++ and we report on two of them here. (A more complete report on this suite will be published when all have been translated and tested.)

The easiest of these is the ``Embarrassingly Parallel'' program. This code generates complex pairs of uniform (0, 1) random numbers and gathers a small number of statistics. In the benchmark the random numbers are created by two special portable functions called vranlc() and randlc(), and a main function compute_pairs(int k) is used to compute the numbers based on a different value of the seed parameter k. The main part of the computation is a loop of the form


     for(i = 1; i < nn; i++) compute_pairs(i);
Our approach is to divide the work into a set of computational engines with one engine per processor. This ``set'' of Engines will be a collection of elements of type Set<GaussianEngine>. Each GaussianEngine object will compute of the total where NODES is the number of processors.

The Engine element class is shown below.


    class GaussianEngine{
      public:
       double  q[nq];  // final result statistics.
        
       double randlc(double *x, double * a);
       void   vranlc(int n, double *x, double a,double *y);
       void   compute_pairs(int kk);
    };

To make a simple set collection we subclass DistributedArray. The main function, computeGauss(), calls an element function do_work() which does all the real computation. The final result statistics are kept in a local array q in each processor. A function sum_resultsis used to do the reduction necessary to sum these values. This involves a simple tree reduction.


    Collection Set: DistributedArray{
      public:
        void computeGauss(void);
      MethodOfElement:
        virtual double q[nq];
        void   do_work(void);
        virtual void   compute_pairs(int kk);
        void sum_results();
    };

    void Set::do_work(void){
      int k;
          for(k = index1+1; k <= nn; k = k+NODES){
                this->compute_pairs(k);
          }
    }

The main routine computeGauss() consists only of computing the random numbers with do_work() and then summing the resulting statistics with sum_results().


beckman@cica.indiana.edu
Mon Nov 21 09:49:54 EST 1994