1

我有一个下面的程序,它应该根据不同的索引分析矩阵乘法的时间。但是有些函数给出了分段错误,其中两个是 matmul_kji(C,A,B) 和 matmul_jki(C,A ,乙)。有人可以向我解释我做错了什么以及可能的改进。此代码应检查从 (1000*1000) 到 (10000*10000) 的矩阵的时序。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>  

using namespace std;
# define MATSIZE 1000


double get_wall_time(){
    struct timeval time;
    if (gettimeofday(&time,NULL)){
        //  Handle error
        return 0;
    }
    return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
double get_cpu_time(){
    return (double)clock() / CLOCKS_PER_SEC;
}  

void init_mat ( double M[MATSIZE][MATSIZE])
{
int i, j;
for (i=0; i<MATSIZE; i++) {
for (j=0; j<MATSIZE; j++) {
M[i][j] = sin(double(i));
}
}
}

void matmul_ijk ( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE]) //1
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (i=0; i<MATSIZE; i++) {
for (j=0; j<MATSIZE; j++) {
aux = 0;
for (k=0; k<MATSIZE; k++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time Of IKJ Ordering = "<< cpu1-cpu0<<endl;
}                      

void matmul_ikj ( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE]) //2
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (i=0; i<MATSIZE; i++) {
for (k=0; k<MATSIZE; k++) {
aux = 0;
for (j=0; j<MATSIZE; j++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time Of IKJ Ordering = "<< cpu1-cpu0<<endl;
}         

void matmul_kij ( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE])  //3
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (k=0; k<MATSIZE; k++) {
for (i=0; i<MATSIZE; i++) {
aux = 0;
for (j=0; j<MATSIZE; j++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time of KIJ ordering = "<< cpu1-cpu0<<endl;
}                      

void matmul_kji( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE]) //4
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (k=0; k<MATSIZE; k++) {
for (j=0; j<MATSIZE; j++) {
aux = 0;
for (i=0; i<MATSIZE; i++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time Of IKJ Ordering = "<< cpu1-cpu0<<endl;
}                      


void matmul_jik( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE])   //5
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (j=0; j<MATSIZE; j++) {
for (i=0; i<MATSIZE; i++) {
aux = 0;
for (k=0; k<MATSIZE; k++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time Of KJI Ordering = "<< cpu1-cpu0<<endl;
}      

void matmul_jki ( double C[MATSIZE][MATSIZE],
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE])   //6
{
int i, j, k;        
double aux;

double cpu0 = get_cpu_time();
for (j=0; j<MATSIZE; j++) {
for (k=0; k<MATSIZE; k++) {
aux = 0;
for (i=0; i<MATSIZE; i++) {
aux += A[i][k] *B[k][j];
}
C[i][j] += aux;
}
}
double cpu1 = get_cpu_time();
cout << "CPU Time Of JKI Ordering = "<< cpu1-cpu0<<endl;
}                   

/*void matmul_ikj( double C[MATSIZE][MATSIZE],              
double A[MATSIZE][MATSIZE], double B[MATSIZE][MATSIZE])
{
int i, j, k;        
double aux;

double cpu0  = get_cpu_time();

for (i=0; i<MATSIZE; i++) {
for (k=0; j<MATSIZE; j++) {
aux = 0;
for (j=0; k<MATSIZE; k++) {
aux += A[i][k]*B[k][j];
}
C[i][j] += aux;
}
}
double cpu1  = get_cpu_time();
cout << "CPU Time  = " << cpu1  - cpu0  << endl;
} */         

int main ()
{
static double A[MATSIZE][MATSIZE];
static double B[MATSIZE][MATSIZE];
static double C[MATSIZE][MATSIZE]= {{0}};

init_mat (A);
init_mat (B);

//matmul_ijk(C,A,B);
//matmul_ikj(C,A,B);  
//matmul_kij(C,A,B);
matmul_kji(C,A,B);      // Gives a segmentation error
//matmul_jik(C,A,B);
matmul_jki(C,A,B);    // Gives a segmentation error

/*for (int i=0; i<10; i++){
    for(int j=0; j < 10; j++){
        cout << C[i][j]<<"  ";
    }
    cout <<endl; } */      

return 0;
}                  
4

2 回答 2

2

这是问题所在:

C[i][j] += aux; // Inside matmul_kji

这是在两个嵌套循环中执行的,其中包含变量jand k,而不是iand j,所以它应该是

C[j][k] = aux;

请注意,您需要替换+==,因为所有添加都已由第三个嵌套循环完成。

另请注意,如果您使用现代*定义循环变量的方式,编译器可以帮助您避免此类问题:而不是预先定义它们,而是在循环头中定义它们,如下所示:

for (int k=0; k<MATSIZE; k++) {
    for (int j=0; j<MATSIZE; j++) {
        double aux = 0;
        for (int i=0; i<MATSIZE; i++) {
            aux += A[i][k] *B[k][j];
        }
        C[i][j] += aux; // <<== Compile error!
    }
}


* “现代”是非常相对的:这种声明循环变量的方式自 80 年代中期就已经存在,使其相当古老。

于 2013-10-26T14:57:28.777 回答
0

i对于未在外循环中设置的两种情况,您可能会遇到分段错误,因为

C[i][j] += aux;
于 2013-10-26T14:57:35.520 回答