我一直在使用并行线程的矩阵乘法,这个代码,但我得到"由大小不同的整数转换为指针"错误
我不知道出了什么问题.我是pthread的新手,这是我到目前为止所做的:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#define NTHREADS 4
int dim ;
pthread_mutex_t m; /* Mutex protecting the sum value */
pthread_t thread_id[NTHREADS]; /* Thread ids */
float **A, **B, **C;
void *prod (void *s){
int *id=(int *)s;
int idd=*id;
/* Define local variables */
int i,j,k, start, end, len ;
float **Aa, **Bb, **Cc;
start = dim*idd; /* Start of this threads slice of the vectors */
end = start + dim; /* End of the slice */
for (i = 0 ; i < dim; i++)
{
for (j = 0; j < dim; j++)
{
Cc[i][j] = 0;
for (i=start; i<end ; i++) {
Cc[i][j] += Aa[i][k] * Bb[k][j];
}
}
}
pthread_mutex_lock (&m); /* Lock the mutex */
C[i][j] += Cc[i][j]; /* Update the shared variable */
pthread_mutex_unlock (&m); /* Unlock the mutex */
pthread_exit(NULL); /* Done! */
}
int main ( int argc, char *argv[] )
{
void *status;
float **A, **B, **C;
int i,j,k;
if ( argc == 2)
dim = atoi(argv[1]); // get the dimension of the matrix
// from the command prompt
else
dim = 128;
A = (float **)malloc(sizeof(float*)*dim);
B = (float **)malloc(sizeof(float*)*dim);
C = (float **)malloc(sizeof(float*)*dim);
for (i = 0 ; i < dim; i++)
{
A[i] = (float *)malloc(sizeof(float)*dim);
B[i] = (float *)malloc(sizeof(float)*dim);
C[i] = (float *)malloc(sizeof(float)*dim);
}
for (i=0; i<dim; i++)
{
for (j = 0 ; j < dim; j++)
{
A[i][j]=rand();
B[i][j]=rand();
}
}
struct timeval t1, t2;
gettimeofday(&t1, NULL);
// you need to parallelize this
// perform the multiplication
for(i=0;i<NTHREADS;i++) {
pthread_create(&thread_id[i], NULL, prod, (void *)i);
}
/* Wait on the other threads */
for(i=0;i<NTHREADS;i++) {
pthread_join(thread_id[i], &status);
}
gettimeofday(&t2, NULL);
double t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec ) / 1000000.0;
// take the difference and report it in seconds
printf("execution time %f seconds\n",t);
}
Run Code Online (Sandbox Code Playgroud)
这一行的错误:
pthread_create(&thread_id[i], NULL, prod, (void *)i);
Run Code Online (Sandbox Code Playgroud)
Giu*_*Pes 31
您错误地使用hack将整数传递给线程.你正在做的事情背后的想法是一个整数是4个字节,指针是x86_32中的4个字节(x86_64中的8个字节)所以我可以将整数类型转换为指针类型,然后将其转换回int类型而不会丢失任何数据.这适用于大多数场景,但不保证指针和整数具有相同的大小.C标准没有规定这一点.
因为你是一个转换的编译器返回一条警告int
到void *
可能有不同的尺寸,(但实际上在你的机器,他们具有相同的大小).
您的代码中存在错误,当您将int转换为void*调用pthead_create函数时,您应该将其转换回整数类型.所以,这一行是错误的:
int *id=(int *)s;
Run Code Online (Sandbox Code Playgroud)
它应该是 :
int id = (int)s;
Run Code Online (Sandbox Code Playgroud)
考虑这个示例,其中线程函数的参数为零.
s=0; therefore ---> *id=(int*)0; // Null pointer
Run Code Online (Sandbox Code Playgroud)
这是指向零地址的指针.当您尝试遵循它时,您可能会遇到分段错误.
执行此操作的最佳方法是使用intptr_t类型.此类型在每个体系结构中具有相同大小的指针(不是int).它的定义如下:
整数类型,能够保存从void指针转换的值,然后转换回该类型,其值等于原始指针.
所以你可以这样做:
#include <stdint.h>
void *threadfunc(void *param)
{
int id = (intptr_t) param;
...
}
int i, r;
r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i);
Run Code Online (Sandbox Code Playgroud)
(此示例代码取自:如何将整数转换为void指针?)
但是,不能保证int的大小与大小相同intptr_t
,但转换过程中某些数据的丢失确实不太可能.
编辑
其他错误:
float **Aa, **Bb, **Cc;
没有初始化. start
并end
超过了数组的限制.矩阵行未分配在连续的存储区中.我会考虑重写矩阵乘法的代码,因为算法是错误的.