Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C OpenMP花费的时间比预期的要多_C_Parallel Processing_Openmp_Hamming Distance - Fatal编程技术网

C OpenMP花费的时间比预期的要多

C OpenMP花费的时间比预期的要多,c,parallel-processing,openmp,hamming-distance,C,Parallel Processing,Openmp,Hamming Distance,因此,我在使用openMp时遇到了一些困难。我是初学者,我不知道我做错了什么。这是我在大学的一门课程的一个项目,因此我不寻求解决方案,而是寻求一个提示或解释 该项目是计算属于不同集合(比如setA和setB)的两个字符串之间的汉明距离。这两个集合可能包含1001000或10000个字符串,每个字符串由相同长度的字符组成 我的问题是,尽管我减少了并行程序的执行时间,但它仍然比串行算法花费更多的时间 因此,我附上我的代码,以显示我迄今为止所做的工作 串行C代码 void main(int argc,

因此,我在使用openMp时遇到了一些困难。我是初学者,我不知道我做错了什么。这是我在大学的一门课程的一个项目,因此我不寻求解决方案,而是寻求一个提示或解释

该项目是计算属于不同集合(比如setA和setB)的两个字符串之间的汉明距离。这两个集合可能包含1001000或10000个字符串,每个字符串由相同长度的字符组成

我的问题是,尽管我减少了并行程序的执行时间,但它仍然比串行算法花费更多的时间

因此,我附上我的代码,以显示我迄今为止所做的工作

串行C代码

void main(int argc,char **argv)
{

//initialize sets' number and string's length
int m=atoi(argv[1]),n=atoi(argv[2]),I=atoi(argv[3]);
int i=0,j=0,l=0,TotalHammingDistance=0,count;

//creation of 2-dimentional matrices for setA and setB
char **setA = malloc(m * sizeof(char *)); // Allocate row pointers
for(i = 0; i < m; i++)
    setA[i] = malloc((I+1) * sizeof(char));  // Allocate each row separatel

char **setB = malloc(n * sizeof(char *)); // Allocate row pointers
for(i = 0; i < n; i++)
    setB[i] = malloc((I+1) * sizeof(char));  // Allocate each row separatel

// initialize matrices with random string (0 and 1)
for (i=0;i<m;i++){
    for(j=0;j<I;j++){
        setA[i][j]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[rand() % 62];
    }
    setA[i][I]='\0';
}

for (i=0;i<n;i++){
    for(j=0;j<I;j++){
        setB[i][j]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[rand() % 62];
    }
    setB[i][I]='\0';
}

//creation of m*n matrix to store all hamming distances and initialize it
int **HamDist = malloc(m * sizeof(int *)); // Allocate row pointers
for(i = 0; i < m; i++)
  HamDist[i] = malloc(n * sizeof(int));

for(i=0;i<m;i++){
    for(j=0;j<n;j++){
        HamDist[i][j]=0;
    }
}

clock_t start=clock();
//Calculate hamming distance for all combinations of the strings
for (i=0;i<m;i++){
    for(j=0;j<n;j++){
        count=0;
        for(l=0;l<=I;l++) {
            if (setA[i][l] != setB[j][l])
                count++;
        }
        HamDist[i][j]=count;
        TotalHammingDistance+=HamDist[i][j];
    }
}
clock_t end =clock();
double hamm_time=(double)(end-start)/CLOCKS_PER_SEC;

printf("\n|Total Hamming execution time= %f",hamm_time);
printf("\n\n*|The Total Hamming Distance is: %d\n",TotalHammingDistance );
} 
void main(int argc,char**argv)
{
//初始化集合的编号和字符串的长度
int m=atoi(argv[1]),n=atoi(argv[2]),I=atoi(argv[3]);
int i=0,j=0,l=0,总汉明距离=0,计数;
//setA和setB二维矩阵的创建
char**setA=malloc(m*sizeof(char*);//分配行指针
对于(i=0;i对于(i=0;i测量多处理器性能有点复杂,但是我们可以用
time(1)
很好地近似“它能工作吗?”。如果我按原样使用您的代码(使用GCC-GCC-4.8.real(Ubuntu 4.8.5-2ubuntu1~14.04.1)4.8.5调用
GCC-W-Wall-Wextra-O3-fopenmp openmptest.c-o openmptest
)我得到

其中,real和user的值大致相同,也与普通版本大致相同。如果我完全删除
计划(dynamic,10000)
,让Openmp自行决定,我得到

$ time ./openmptest 10000 10000 100
 HamDist set 

|Total time for two sets= 9.187761
|Total execution time= 9.187761

*|The Total Hamming Distance is: 1248788142

real    0m4.819s
user    0m9.265s
sys 0m0.112s
这是5/9而不是9/9。如果我将
omp\u set\u num\u threads(2)
设置为4(我这里有四个CPU),我得到

这是3/11<5/9<9/9。因此,如果您让OpenMP自己来做,它会像预期的那样工作。删除
omp\u set\u num\u threads()
与上次尝试没有任何区别

您有一个非常简单的程序,其中OpenMP的默认值工作得非常好。微调OpenMP本身就是一门科学,但例如@Davidslor关于使用
reduce
的评论似乎是一个很好的开始


顺便说一句:你也有很多警告,其中一个是关于阴影
count
,你声明了两次,一次在循环之前,一次在循环内部。你应该去掉所有的警告。经常发生的情况是,在这几十个警告之间隐藏了非常重要的信息。

您正在测试此功能的计算机有多长?从中获取基准数据的字符串有多长?如果字符串太短,则创建线程的开销将超过分配工作负载的好处。请测量您在所有这些
malloc()中花费的时间
调用。并打开所有编译器警告。您也可能在
setB[i][j]=“0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvxyz”[rand()%62];
中花费了大量时间,其中
m=n=10000
@AlexQuilliam我的计算机有4个内核。我计算了2、4和6个线程的执行时间。使用2个线程,我得到了文章中描述的结果。字符串长度为100个字符。工作负载(或块大小)我们发现到目前为止最好的解决方案是1000。@AndrewHenle我没有测量初始化表的时间。我只测量汉明距离计算的时间。您可能希望将
omp\u get\u num\u threads()
设置为
omp\u get\u max\u threads()
而不是2。在编译时说出真相(gcc-fopenmp-o openmptest openmptest.c)除了两次声明的变量计数之外,我没有收到任何警告。尽管如此,在更正所有警告并按照您的建议执行后,时间明显更好!感谢您的帮助!@sotirisdimitra为什么您没有收到警告…哦,我的错,对不起。我使用了clang的“偏执狂”模式
clang-Weverything…
生成警告,因为它的静态分析器比GCC的好,并且忘记了将强制的
-W-Wall-Wextra
添加到GCC调用行,所以:我的错,抱歉。
$ time ./openmptest 10000 10000 100

 HamDist set 

|Total time for two sets= 9.620011
|Total execution time= 9.620011

*|The Total Hamming Distance is: 1248788142

real    0m9.815s
user    0m9.700s
sys 0m0.116s
$ time ./openmptest 10000 10000 100
 HamDist set 

|Total time for two sets= 9.187761
|Total execution time= 9.187761

*|The Total Hamming Distance is: 1248788142

real    0m4.819s
user    0m9.265s
sys 0m0.112s
$ time ./openmptest 10000 10000 100
 HamDist set 

|Total time for two sets= 11.438243
|Total execution time= 11.438243

*|The Total Hamming Distance is: 1248788142

real    0m3.080s
user    0m11.540s
sys 0m0.104s