[英]Pthreads matrix multiplication error
我想在现有的串行矩阵乘法代码上使用pthreads。 我的目标是使用pthreads来获得更好的执行时间,只是为了提高速度。 但是那时我被困住了。 我原来的串行代码工作正常,大约15秒钟即可完成1000x1000方阵乘法。 但是,当我执行当前的pthreads程序时,出现了分段错误。 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
int SIZE, NTHREADS;
int **A, **B, **C;
void init()
{
int i, j;
A = (int**)malloc(SIZE * sizeof(int *));
for(i = 0; i < SIZE; i++)
A[i] = malloc(SIZE * sizeof(int));
B = (int**)malloc(SIZE * sizeof(int *));
for(i = 0; i < SIZE; i++)
B[i] = malloc(SIZE * sizeof(int));
C = (int**)malloc(SIZE * sizeof(int *));
for(i = 0; i < SIZE; i++)
C[i] = malloc(SIZE * sizeof(int));
srand(time(NULL));
for(i = 0; i < SIZE; i++) {
for(j = 0; j < SIZE; j++) {
A[i][j] = rand()%100;
B[i][j] = rand()%100;
}
}
}
void mm(int tid)
{
int i, j, k;
int start = tid * SIZE/NTHREADS;
int end = (tid+1) * (SIZE/NTHREADS) - 1;
for(i = start; i <= end; i++) {
for(j = 0; j < SIZE; j++) {
C[i][j] = 0;
for(k = 0; k < SIZE; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
void *worker(void *arg)
{
int tid = *((int *) arg);
mm(tid);
}
int main(int argc, char* argv[])
{
pthread_t* threads;
int rc, i;
if(argc != 3)
{
printf("Usage: %s <size_of_square_matrix> <number_of_threads>\n", argv[0]);
exit(1);
}
SIZE = atoi(argv[1]);
NTHREADS = atoi(argv[2]);
init();
threads = (pthread_t*)malloc(NTHREADS * sizeof(pthread_t));
clock_t begin, end;
double time_spent;
begin = clock();
for(i = 0; i < NTHREADS; i++) {
rc = pthread_create(&threads[i], NULL, worker, (void *)i);
assert(rc == 0);
}
for(i = 0; i < NTHREADS; i++) {
rc = pthread_join(threads[i], NULL);
assert(rc == 0);
}
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Elapsed time: %.2lf seconds.\n", time_spent);
for(i = 0; i < SIZE; i++)
free((void *)A[i]);
free((void *)A);
for(i = 0; i < SIZE; i++)
free((void *)B[i]);
free((void *)B);
for(i = 0; i < SIZE; i++)
free((void *)C[i]);
free((void *)C);
free(threads);
return 0;
}
如果有人可以帮助我使我的pthreads程序运行并提高速度,我会很高兴。
使用当前代码,您应该使用
int tid = (int)arg;
(您的代码有效地将循环计数器视为一个地址,然后在0或附近解引用地址。这些地址可能无法被您的进程读取和/或无法适当对齐,因此出现了段错误)
上面的更改可能会让您工作起来,但是请注意,将int
作为void*
传递并不完全正确。 它依赖于sizeof(int) <= sizeof(void*)
,这很可能但不能保证为真。 如果您对此有所关注,则可以为传递给每个线程的数据分配内存,或者传递i
的地址并包括同步以确保您在每个pthread_create
调用之后等待,直到线程被调度并读取了它的arg。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.