Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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 为什么多线程比单线程慢?_C_Pthreads_Openmp_Matrix Multiplication - Fatal编程技术网

C 为什么多线程比单线程慢?

C 为什么多线程比单线程慢?,c,pthreads,openmp,matrix-multiplication,C,Pthreads,Openmp,Matrix Multiplication,我编写了一个并行pthreads程序,计算 两个n*n大小的矩阵。右矩阵是垂直分区的。用户输入矩阵大小n和螺纹数(p),以便: 并行计算涉及到pthread 采用矩阵乘法的一维并行算法: 右矩阵在一维中被划分为p个相等的切片(A*B,然后B被划分为p个切片) 分区和线程之间有一对一的映射 每个线程负责计算结果矩阵的相应切片 守则: double *A; double *B; double *C; int n; double matrix_norm; typedef struct { do

我编写了一个并行pthreads程序,计算 两个n*n大小的矩阵。右矩阵是垂直分区的。用户输入矩阵大小n和螺纹数(p),以便:

  • 并行计算涉及到pthread
  • 采用矩阵乘法的一维并行算法:
  • 右矩阵在一维中被划分为p个相等的切片(A*B,然后B被划分为p个切片)
  • 分区和线程之间有一对一的映射
  • 每个线程负责计算结果矩阵的相应切片
  • 守则:

    double *A;
    double *B;
    double *C;
    int n;
    double matrix_norm;
    
    typedef struct {
       double *b;
       double *c;
       int num_of_columns;
       pthread_mutex_t *mutex;
    } matrix_slice;
    
    void *matrix_slice_multiply(void *arg){
       matrix_slice *slice = arg;
       int i, j;
       cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, n, slice->num_of_columns, n, 1.0, A, n, slice->b, n, 0.0, slice->c, n);
    
       // compute column norm of each slice
       double slice_norm = 0.0;
       for(j = 0; j < slice->num_of_columns; j++) {
          double column_sum=0.;
          for(i = 0; i < n; i++)
             column_sum += *(slice->c + i * n + j);
    
          if(column_sum>slice_norm)
             slice_norm=column_sum;
       }
       pthread_mutex_lock(slice->mutex);
       if (slice_norm>matrix_norm)
          matrix_norm=slice_norm;
       pthread_mutex_unlock(slice->mutex);
    
       pthread_exit(NULL);
    }
    
    int main(void) {
       int num_of_thrds, num_of_columns_per_slice;
       pthread_t *working_thread;
       matrix_slice *slice;
       pthread_mutex_t *mutex;
       int i = 0;
    
       printf ("Please enter matrix dimension n : "); 
       scanf("%d", &n); 
    
       printf ("Please enter number of threads : "); 
       scanf("%d", &num_of_thrds);
    
       while (num_of_thrds > n) {
          printf("number of threads must not be greater than matrix dimension\n");
          printf ("Please enter number of threads : "); 
          scanf("%d", &num_of_thrds);
       }
       // allocate memory for the matrices
       ///////////////////// Matrix A //////////////////////////
       A = (double *)malloc(n * n * sizeof(double));
    
       if (!A) {
          printf("memory failed \n");
          exit(1);
       }
    
       ///////////////////// Matrix B //////////////////////////
       B = (double *)malloc(n * n * sizeof(double));  
       if (!B) {
          printf("memory failed \n");
          exit(1);
       }
    
       ///////////////////// Matrix C //////////////////////////
       C = (double *)malloc(n * n * sizeof(double)); 
       if (!C) {
          printf("memory failed \n");
          exit(1);
       }
    
       // initialize the matrices
       for (i = 0; i < n * n; i++) {        
          A[i] = rand() % 15;
          B[i] = rand() % 10;       
          C[i] = 0.;
       }
    
       clock_t t1 = clock();    
       working_thread = malloc(num_of_thrds * sizeof(pthread_t));
       slice = malloc(num_of_thrds * sizeof(matrix_slice));
       mutex = malloc(sizeof(pthread_mutex_t));
       num_of_columns_per_slice = n / num_of_thrds;
    
       for(i = 0; i < num_of_thrds; i++){
          slice[i].b = B + i * num_of_columns_per_slice;
          slice[i].c = C + i * num_of_columns_per_slice;
          slice[i].mutex = mutex;
          slice[i].num_of_columns = (i == num_of_thrds - 1) ? n-i * num_of_columns_per_slice : num_of_columns_per_slice;
          pthread_create(&working_thread[i], NULL, matrix_slice_multiply, (void *)&slice[i]);
       }
       for(i = 0; i < num_of_thrds; i++)
          pthread_join(working_thread[i], NULL);
    
       clock_t t2=clock();
       printf("elapsed time: %f\n", (double)(t2 - t1)/CLOCKS_PER_SEC);   
    
       printf("column sum norm is %f\n", matrix_norm);  
    
       //deallocate memory  
       free(A);   
       free(B);   
       free(C);       
       free(working_thread);
       free(slice);
    
       return 0;
    }
    
    double*A;
    双*B;
    双*C;
    int n;
    双矩阵_范数;
    类型定义结构{
    双*b;
    双*c;
    整列的整数;
    pthread_mutex_t*mutex;
    }矩阵u切片;
    void*矩阵\切片\乘法(void*arg){
    矩阵_slice*slice=arg;
    int i,j;
    cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,n,slice->num_of_columns,n,1.0,A,n,slice->b,n,0.0,slice->c,n);
    //计算每个切片的列范数
    双层_范数=0.0;
    对于(j=0;jnum\u of_columns;j++){
    双列总和=0。;
    对于(i=0;ic+i*n+j);
    if(列总和>切片标准)
    切片=列和;
    }
    pthread_mutex_lock(slice->mutex);
    if(切片\u范数>矩阵\u范数)
    矩阵_范数=切片_范数;
    pthread_mutex_unlock(slice->mutex);
    pthread_exit(NULL);
    }
    内部主(空){
    int num_of_thrds,num_of_columns_/_slice;
    pthread_t*工作线程;
    矩阵_切片*切片;
    pthread_mutex_t*mutex;
    int i=0;
    printf(“请输入矩阵维数n:”);
    scanf(“%d”和“&n”);
    printf(“请输入线程数:”);
    scanf(“%d”和数量);
    while(总数>n){
    printf(“线程数不得大于矩阵维数\n”);
    printf(“请输入线程数:”);
    scanf(“%d”和数量);
    }
    //为矩阵分配内存
    /////////////////////矩阵A//////////////////////////
    A=(双*)malloc(n*n*sizeof(双));
    如果(!A){
    printf(“内存失败\n”);
    出口(1);
    }
    /////////////////////矩阵B//////////////////////////
    B=(双*)malloc(n*n*sizeof(双));
    如果(!B){
    printf(“内存失败\n”);
    出口(1);
    }
    /////////////////////矩阵C//////////////////////////
    C=(双*)malloc(n*n*sizeof(双));
    如果(!C){
    printf(“内存失败\n”);
    出口(1);
    }
    //初始化矩阵
    对于(i=0;i

    我用各种输入运行了几十次程序,结果表明,使用的线程越多,花费的时间就越多。这完全违反直觉。更多的线程是否有助于提高性能?

    在执行可能导致程序等待资源的操作(如对文件系统或网络的读/写)时,使用线程有助于提高应用程序的性能,但如果没有这样的操作,创建线程的开销,获取和释放互斥量以及在线程之间执行上下文切换可能会降低应用程序的速度。

    并行运行计算所节省的开销需要大于创建、维护和在线程之间切换的开销。与其使用大量线程运行几十次,不如使用与系统上的内核数量相同的线程运行一次单个非常大的操作。

    好的,您使用clock()来测量时间,它将测量总CPU时间,而不是墙上的时钟时间。矩阵的维度是什么?创建线程会导致一些开销;如果你的矩阵不够大,那么开销可能比多线程节省的开销要大。作为建议:请下次缩进代码,这是无法理解的。非常感谢,不。你的答案正是我想要的。我肯定会用墙上的时钟。不客气。如果其中一个答案对您有帮助,您应该单击该答案旁边的复选标记将其标记为已接受。