进行矩阵乘法时C++中的分段错误
Segmentaion fault in C++ when doing matrix multiplication
>我在下面有一个程序,它应该根据不同的索引分析矩阵乘法的时间。但是一些函数给出了分割错误,其中两个是matmul_kji(C,A,B)和matmul_jki(C,A,B)。有人可以向我解释我做错了什么以及可能的改进。此代码应检查从 (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;
}
这是问题所在:
C[i][j] += aux; // Inside matmul_kji
这是在两个嵌套循环中执行的,变量为 j
和 k
,而不是 i
和 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!
}
}
*"现代"是非常相对的:这种声明循环变量的方式自八十年代中期以来就已经存在,使其相当古老。
对于
未在外部循环中设置i
的两种情况,您可能会遇到分段错误,因为
C[i][j] += aux;
相关文章:
- 分段故障(堆芯转储)矢量
- 数组的指针从不分段故障
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)