我在ubuntu中使用L1 Cache优化编写了一个优化矩阵乘法的程序。 我收到了分段错误(核心转储)错误。 我查看了我的所有malloc函数,但没有找到bug。 我不知道如何解决它。 这是代码:
#include<sys/types.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <sys/wait.h>
#define N 100
#define THREAD_NUM 1
void thread_func(void *arg){
printf("thread start \n");
int i,j,k,i2,j2,k2;
double **a;
double **b;
double **c;
double *aa,*bb,*cc;
a = (double**)malloc(sizeof(double*)*N);
for (i=0; i<N; i++)
a[i] = (double*)malloc(sizeof(double)*N);
b = (double**)malloc(sizeof(double*)*N);
for (i=0; i<N; i++)
b[i] = (double*)malloc(sizeof(double)*N);
c = (double**)malloc(sizeof(double*)*N);
for (i=0; i<N; i++)
c[i] = (double*)malloc(sizeof(double)*N);
srand((unsigned)time(NULL));
for(i = 0; i < N; i++)
for(j = 0; j <N; j++)
*(*(a+i)+j) = 555.123;
for(i = 0; i < N; i++)
for(j = 0; j <N; j++){
*(*(b+i)+j) = 666.456;
}
for(i = 0; i < N; i++)
for(j = 0; j <N; j++){
*(*(c+i)+j) = 0.0;
}
/*
for(i = 0; i < N; i+=8)
for(j = 0; j < N; j+=8)
for(k = 0; k < N; k+=8)
for(i2=0,cc=&(*(*(c+i)+j)),aa=&(*(*(a+i)+k));i2<8;++i2,cc+=N,aa+=N)
for(k2=0,bb=&(*(*(b+k)+j));k2<8;++k2,bb+=N)
for(j2=0;j2<8;++j2){
*(cc+j2)+=*(aa+k2)*(*(bb+j2));
//printf("cc ,*(cc+j2)%d %d\n",cc,*(cc+j2));
}
*/
for(i = 0; i < N; i+=8)
for(j = 0; j < N; j+=8)
for(k = 0; k < N; k+=8)
for(i2=0, cc=(*(c+i)+j), aa=(*(a+i)+k); i2<8; ++i2,cc+=N,aa+=N)
for(k2=0, bb=(*(b+k)+j); k2<8; ++k2, bb+=N)
for(j2=0; j2<8; ++j2){
*(cc+j2)+=(*(aa+k2))*(*(bb+j2));
}
printf("ready to free \n");
//free(aa); free(bb);free(cc);
for (i=0; i<N; i++)
free(a[i]); free(b[i]);free(c[i]);
free(a);free(b);free(c);
printf("thread done \n");
}
int main(void)
{
printf("program start \n");
int i;
pthread_t handle[THREAD_NUM];
for( i=0;i<THREAD_NUM;i++)
pthread_create(&handle[i],NULL,(void*)thread_func,NULL);
for(i=0;i<THREAD_NUM;i++)
pthread_join(handle[i],NULL);
perror("a*b leaveing");
return 0;
}
答案 0 :(得分:3)
您写道:
for (i=0; i<N; i++)
free(a[i]); free(b[i]);free(c[i]);
编译器将其视为:
for (i=0; i<N; i++)
free(a[i]);
free(b[i]);
free(c[i]);
这必须尝试访问/释放数据超出范围。它也泄漏了大量内存。使用大括号和空格 - 它们很便宜。使用多行;它们也很便宜。
for (i = 0; i < N; i++)
{
free(a[i]);
free(b[i]);
free(c[i]);
}
您还应该检查每次内存分配是否成功,但如果您尝试使用未成功分配的数组,则会崩溃。
你为什么要写作:
*(*(a+i)+j) = 555.123;
编译器会像写a[i][j]
一样对待它,这样可以减少键入内容和更清晰阅读的痛苦。
答案 1 :(得分:1)
程序中存在一些缺陷,如果你修复它们应该可以正常工作:
1)你的自由内存循环不正确。它仅为[i]循环,b [i]和c [i]不在循环内部考虑。使用以下代码:
for (i = 0; i < N; i++)
{
free(a[i]);
free(b[i]);
free(c[i]);
}
2)我在下面给出的代码中发现了另一个问题,标有“问题代码”。这里BB + J2超出界限,导致内存损坏。
for(i = 0; i < N; i+=8)
for(j = 0; j < N; j+=8)
for(k = 0; k < N; k+=8)
for(i2=0, cc=(*(c+i)+j), aa=(*(a+i)+k); i2<8; ++i2,cc+=N,aa+=N)
for(k2=0, bb=(*(b+k)+j); k2<8; ++k2, bb+=N)
for(j2=0; j2<8; ++j2){
*(cc+j2)+=(*(aa+k2))*(*(bb+j2)); /* PROBLEMATIC CODE */
}
您可以使用valgrind工具(memcheck)找出问题。