gpt4 book ai didi

c - Pthread 程序花费比预期更长的时间

转载 作者:太空宇宙 更新时间:2023-11-04 07:33:15 25 4
gpt4 key购买 nike

你好,

我已经创建了一个多线程应用程序,用于使用 pthreads 将两个矩阵相乘,但令我惊讶的是,多线程程序花费的时间比我预期的要多。

我不知道我的代码哪里有问题,代码片段如下:

#include "pthreads.h"
#include "cv.h"
#include "cxcore.h"

CvMat * matA; /* first matrix */
CvMat * matB; /* second matrix */
CvMat * matRes; /* result matrix */

int size_x_a; /* this variable will be used for the first dimension */
int size_y_a; /* this variable will be used for the second dimension */

int size_x_b,size_y_b;
int size_x_res;
int size_y_res;

struct v {
int i; /* row */
int j; /* column */
};


void *printThreadID(void *threadid)
{
/*long id = (long) threadid;
//printf("Thread ID: %ld\n", id);

arrZ[id] = arrX[id] + arrY[id];

pthread_exit(NULL);*/
return 0;
}

int main()
{
/* assigining the values of sizes */
size_x_a = 200;
size_y_a = 200;
size_x_b = 200;
size_y_b = 200;

/* resultant matrix dimensions */
size_x_res = size_x_a;
size_y_res = size_y_b;

matA = cvCreateMat(size_x_a,size_y_a,CV_64FC1);
matB = cvCreateMat(size_x_b,size_y_b,CV_64FC1);
matRes = cvCreateMat(size_x_res,size_y_res,CV_64FC1);

pthread_t thread1;
pthread_t thread2;
pthread_t multThread[200][200];

int res1;
int res2;
int mulRes;
/*******************************************************************************/

/*Creating a thread*/
res1 = pthread_create(&thread1,NULL,initializeA,(void*)matA);
if(res1!=0)
{
perror("thread creation of thread1 failed");
exit(EXIT_FAILURE);
}


/*Creating a thread*/
res2 = pthread_create(&thread2,NULL,initializeB,(void*)matB);

if(res2!=0)
{
perror("thread creation of thread2 failed");
exit(EXIT_FAILURE);
}


pthread_join(thread1,NULL);
pthread_join(thread2,NULL);

/*Multiplication of matrices*/
for(int i=0;i<size_x_a;i++)
{
for(int j=0;j<size_y_b;j++)
{
struct v * data = (struct v*)malloc(sizeof(struct v));
data->i = i;
data->j = j;

mulRes = pthread_create(&multThread[i][j],NULL,multiplication, (void*)data);
}
}

for(int i=0;i<size_x_a;i++)
{
for(int j=0;j<size_y_b;j++)
{
pthread_join(multThread[i][j],NULL);
}
}


for(int i =0;i<size_x_a;i++)
{
for(int j = 0;j<size_y_a;j++)
{
printf("%f ",cvmGet(matA,i,j));
}
}
return 0;
}

void * multiplication(void * param)
{
struct v * data = (struct v *)param;
double sum =0;
for(int k=0;k<size_x_a;k++)
sum += cvmGet(matA,data->i,k) * cvmGet(matB,k,data->j);

cvmSet(matRes,data->i,data->j,sum);
pthread_exit(0);

return 0;
}

void * initializeA(void * arg)
{
CvMat * matA = (CvMat*)arg;
//matA = (CvMat*)malloc(size_x_a * sizeof(CvMat *));

/*initialiazing random values*/
for (int i = 0; i < size_x_a; i++)
{
for (int j = 0; j < size_y_a; j++)
{
cvmSet(matA,i,j,size_y_a + j); /* just some unique number for each element */
}
}
return 0;
}

void * initializeB(void * arg)
{
CvMat* matB = (CvMat*)arg;
//matB = (CvMat*)malloc(size_x_b * sizeof(CvMat *));

/*initialiazing random values*/
for (int i = 0; i < size_x_b; i++)
{
for (int j = 0; j < size_y_b; j++)
{
cvmSet(matB,i,j,size_y_b + j); /* just some unique number for each element */
}
}
return 0;
}

void * initializeRes(void * arg)
{
CvMat * res = (CvMat*)arg;
//res = (CvMat*)malloc(size_x_res * sizeof(CvMat *));

/* for matrix matRes, allocate storage for an array of ints */
for (int i = 0; i < size_x_res; i++)
{
for (int j = 0; j < size_y_res; j++)
{
cvmSet(matRes,i,j,0);
}
}
return 0;
}

我是第一次做这种多线程。请帮助我解决这个问题,任何建议或更正都会非常有帮助。

提前致谢。

最佳答案

您正在创建大量线程,这将涉及大量上下文切换。如果每个线程都在进行纯计算,并且不涉及任何类型的等待(如网络、套接字等),那么线程化就没有理由比非线程化更快。当然,除非您使用的是多 CPU/内核机器,否则您应该为每个内核创建一个线程。对于这种处理,线程多于内核只会减慢速度。

您可以做的是将工作集划分为可以排队的任务,并使用工作线程(一个/CPU 核心)将任务从公共(public)工作队列中拉出。这是一个标准的生产者/消费者问题。

Here是关于生产者/消费者问题的一些通用信息。

我已经很久没有做矩阵乘法了,所以请耐心等待 :) 看起来你可以将以下内容分成单独的任务:

/*Multiplication of matrices*/
for(int i=0;i<size_x_a;i++)
{
for(int j=0;j<size_y_b;j++)
{
struct v * data = (struct v*)malloc(sizeof(struct v));
data->i = i;
data->j = j;

/* Instead of creating a thread, create a task and put it on the queue
* mulRes = pthread_create(&multThread[i][j],NULL,multiplication, (void*)data);
*/

/* Im not going to implement the queue here, since there are several available
* But remember that the queue access MUST be mutex protected. */
enqueue_task(data);
}
}

之前,您必须创建所谓的线程池(工作线程,每个 CPU 核心一个),其工作函数将尝试拉出队列并执行工作。有一些方法可以使用 pthread 条件变量来执行此操作,如果队列为空,线程将被阻塞/等待 cond var,一旦队列被填充,cond var 就会收到信号,从而释放线程以便它们可以启动工作。

如果这不是逻辑上的分工,而你找不到,那么可能这个问题不适合多线程。

关于c - Pthread 程序花费比预期更长的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11410450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com