ページ 11

OpenMPについて

Posted: 2015年11月15日(日) 21:22
by yman
OpenMPを使って相関係数を求めるコードを高速化したいと思っています。自分で書いた相関係数を計算するプログラムが以下です。これを書き換えて時間を比較したいと思うのですが、OpenMPの関数に関しては勉強中でどのように書き換えれば良いかがわかりません。詳しい方、教えていただけると幸いです。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include <omp.h>

int main(int argc, char** argv) {
  if (argc != 2) {
    fprintf(stderr, "Usage: avg num_elements_per_proc\n");
    exit(1);
  }

  int num_elements_per_proc = atoi(argv[1]);
 
 // Creates sin numbers
 long num_elements = atoi(argv[1]);
 double *sin_nums_a = (double *)malloc(sizeof(double) * num_elements);
 double *sin_nums_b = (double *)malloc(sizeof(double) * num_elements);

double total_time = 0.0; 

for(long i=0; i<num_elements; i++){
    sin_nums_a[i] = sin(i);
    sin_nums_b[i] = sin(i+2);
 }

//Time start
 clock_t start,end;
 start = clock();


// Sum the numbers
  
  float sum_X = 0;
  float sum_Y = 0;

  int i;
  
  for (i = 0; i < num_elements_per_proc; i++) {
    sum_X += sin_nums_a[i];
    sum_Y += sin_nums_b[i];
    }


//Calculate the mean
  float mean_X = sum_X / num_elements_per_proc ;
  float mean_Y = sum_Y / num_elements_per_proc ;

// Compute the sum of the squared differences from the mean
  float sq_diff_X = 0;
  float sq_diff_Y = 0;
  
  for (i = 0; i < num_elements_per_proc; i++) {
    sq_diff_X += (sin_nums_a[i] - mean_X) * (sin_nums_a[i] - mean_X);
    sq_diff_Y += (sin_nums_b[i] - mean_Y) * (sin_nums_b[i] - mean_Y);
  }

// Compute the sum of differences from the mean
  float sum_diff_XY;
  
  for (i = 0; i < num_elements_per_proc; i++) {
    float diff_X = (sin_nums_a[i] - mean_X);
    float diff_Y = (sin_nums_b[i] - mean_Y);

    float diff_XY = diff_X * diff_Y;
    sum_diff_XY += diff_XY;
    }

// The Pearson Correlation Coefficient
    float stddev_X = sqrt(sq_diff_X /
                        num_elements_per_proc);
    float stddev_Y = sqrt(sq_diff_Y /
                        num_elements_per_proc);

 
end = clock();
 double time_per_test = (double)(end-start)/CLOCKS_PER_SEC;
 

    printf("Mean X - %f, Standard deviation of X = %f\nMean Y - %f, Standard deviation of Y = %f\n ", mean_X, stddev_X, mean_Y, stddev_Y);
  printf("Time = %f\n", time_per_test);

Re: OpenMPについて

Posted: 2015年11月16日(月) 02:49
by yman
現在、OpenMPを勉強しながら進めていますが、以下の状態です。どなたか教えていただけるとありがたいです...

コード:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include <omp.h>
 
int main(int argc, char** argv) {
  if (argc != 2) {
    fprintf(stderr, "Usage: avg num_elements_per_proc\n");
    exit(1);
  }
 
  int num_elements_per_proc = atoi(argv[1]);
 
 // Creates sin numbers
 long num_elements = atoi(argv[1]);
 double *sin_nums_a = (double *)malloc(sizeof(double) * num_elements);
 double *sin_nums_b = (double *)malloc(sizeof(double) * num_elements);
 
double total_time = 0.0; 
 
for(long i=0; i<num_elements; i++){
    sin_nums_a[i] = sin(i);
    sin_nums_b[i] = sin(i+2);
 }
 
//Time start
 clock_t start,end;
 start = clock();
 

// Sum the numbers
  
  float sum_X = 0;
  float sum_Y = 0;
 
  int i;
  #pragma omp parallel for reduction(+:sum_X)(+:sum_Y)
  for (i = 0; i < num_elements_per_proc; i++) {
    sum_X += sin_nums_a[i];
    sum_Y += sin_nums_b[i];
    }
 
 
//Calculate the mean
  float mean_X = sum_X / num_elements_per_proc ;
  float mean_Y = sum_Y / num_elements_per_proc ;
 
// Compute the sum of the squared differences from the mean
  float sq_diff_X = 0;
  float sq_diff_Y = 0;
  
 #pragma omp parallel for reduction(+:sq_diff_X)(+:sq_diff_Y)
  for (i = 0; i < num_elements_per_proc; i++) {
    sq_diff_X += (sin_nums_a[i] - mean_X) * (sin_nums_a[i] - mean_X);
    sq_diff_Y += (sin_nums_b[i] - mean_Y) * (sin_nums_b[i] - mean_Y);
  }
 
// Compute the sum of differences from the mean
  float sum_diff_XY;
  
#pragma omp parallel reduction(+:diff_X)(+:diff_Y)
  for (i = 0; i < num_elements_per_proc; i++) {
    float diff_X = (sin_nums_a[i] - mean_X);
    float diff_Y = (sin_nums_b[i] - mean_Y);
 
    float diff_XY = diff_X * diff_Y;
    sum_diff_XY += diff_XY;
    }
 
// The Pearson Correlation Coefficient
    float stddev_X = sqrt(sq_diff_X /
                        num_elements_per_proc);
    float stddev_Y = sqrt(sq_diff_Y /
                        num_elements_per_proc);
 
 
end = clock();
 double time_per_test = (double)(end-start)/CLOCKS_PER_SEC;
 
 
    printf("Mean X - %f, Standard deviation of X = %f\nMean Y - %f, Standard deviation of Y = %f\n ", mean_X, stddev_X, mean_Y, stddev_Y);
  printf("Time = %f\n", time_per_test);