So, I believe that the code below, even though I see no errors, is not being able to parallelize my performance and acts as if it is a normal single thread program.
Using OpenMP
in C, I am trying to find the intersections between adjacency lists read from a file. I don't know whether my code is I/O bound, or my directives are not placed correctly, loop is incorrect, the way I am recording time or can it be due to some system requirements? The omp_set_num_threads()
seems to work fine.
Anything you guys think I should check that may be the problem with OpenMP
, I would be glad to know. I know it's something related to OMP
as I have written a similar code in MPI
that gives the expected performance. Thanks!
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#define MAX 20000 //number of vertices we are working with
#define EACHLINE 99000 //max chars each line of file could possess
int *allLines[MAX]; //stores all the lines, hopefully
int lengths[MAX];
int lines = 0;
//function for getting intersecton of two arrays
void getIntersections(int *one, int *two, int l1, int l2){
//arrays and their sizes
#pragma omp critical
{
printf("%d & %d: [ ", *one, *two);
for(int o=1; o<l1; o++){
for(int t=1; t<l2; t++){
if(*(one+o)==*(two+t)){
printf("%d ", *(one+o));
break;
}
}
}
printf("]\n");
}
}
//getting common ones out of the adjacency lists with vertices v1 & v2
void getLists(int v1, int v2){
int r, s, length1, length2;
int *arr1, *arr2;
int done = 0;
for(r=0; r<lines; r++){
if( *(allLines[r]) == v1){
int *arr11 = malloc(sizeof(int)*lengths[r]);
length1 = lengths[r];
arr11 = allLines[r];
arr1 = arr11;
if(done>0)
break;
done = 1;
}
else if( *(allLines[r]) == v2){
int *arr22 = malloc(sizeof(int)*lengths[r]);
length2 = lengths[r];
arr22 = allLines[r];
arr2 = arr22;
if(done>0)
break;
done = 1;
}
}
getIntersections(arr1, arr2, length1, length2);
}
int main(int argc, char** argv){
//getting number of lines in file
FILE *tp = fopen("r2.txt","r");
int ch=0;
while ((ch = fgetc(tp)) != EOF){
if (ch == '\n')
lines++;
}
fclose(tp);
FILE* fp;
if((fp = fopen("r2.txt", "r")) == NULL){ //opens file
perror("Error opening file!");
return 1;
}
char input[EACHLINE];
for(int g = 0; g < lines; g++){ //dividing task among processes
int arr[MAX], length = 0, c, bytesread;
fgets(input, sizeof(input), fp);
char* str = input; //list buffer
while (sscanf(str, "%d%n", &c, &bytesread) > 0) { \
//changing string of spaced numbers to int array
arr[length++] = c;
str += bytesread;
}
int *rr = malloc(sizeof(int)*length);
for(int i=0; i < length; i++) {
*(rr+i) = arr[i];
}
allLines[g] = rr;
lengths[g] = length;
}
clock_t start, end; //clocks
double cpu_time_used; //time recorder
start = clock();
omp_set_num_threads(81);
int r, s;
#pragma omp parallel private(r, s) shared(lengths, allLines, lines)
{
#pragma omp for
for(r=0; r<lines; r++){
for(s=0; s < lengths[r]; s++){
if( *(allLines[r]) < *(allLines[r]+s) ){
getLists( *(allLines[r]), *(allLines[r]+s) );
}
}
}
}
end = clock(); //timer stop
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
//time taken
printf("Time: %f\n", cpu_time_used);
for(int k=0; k<lines; k++)
free(allLines[k]);
fclose(fp);
return 0;
}