Reputation: 15574
I'm using the following C++ code to do matrix multiplication and it runs fine for SIZE = 500. But when SIZE = 600 or above the code fails. (Runtime Error)
I ran it on Ideone.com It ouputs "Runtime error time: 0 memory: 3292 signal:11"
and also In my local machine too it is giving me an error
#include <cstdlib>
#include<iostream>
#include <stdio.h>
#include <sys/time.h>
using namespace std;
class Timer {
private:
timeval startTime;
public:
void start(){
gettimeofday(&startTime, NULL);
}
double stop(){
timeval endTime;
long seconds, useconds;
double duration;
gettimeofday(&endTime, NULL);
seconds = endTime.tv_sec - startTime.tv_sec;
useconds = endTime.tv_usec - startTime.tv_usec;
duration = seconds + useconds/1000000.0;
return duration;
}
static void printTime(double duration){
printf("%5.6f seconds\n", duration);
}
};
using namespace std;
const int SIZE = 600; // for size*size matrix
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
int i,j,k;
double s;
/*
*
*/
int main(int argc, char** argv) {
double a[SIZE][SIZE], b[SIZE][SIZE], ans[SIZE][SIZE];
// assign the numbers for matrix a and b
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
a[i][j]=(double)rand()/RAND_MAX;
b[i][j]=(double)rand()/RAND_MAX;
}
}
MultiplyMatricesSequential(a,b,ans);
return 0;
}
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE])
{
Timer timer = Timer();
timer.start();
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
for (k = 0; k < SIZE; k++)
s += a[i][k] * b[k][j];
ans[i][j] = s;
s = 0.0;
}
}
double duration = timer.stop();
cout << "Sequential Method time elapsed for SIZE " << SIZE << " : ";
timer.printTime(duration);
}
So what am I doing wrong here ?
NOTE : It is still the same when timer is not used.
#include <cstdlib>
#include<iostream>
#include <stdio.h>
#include <sys/time.h>
using namespace std;
const int SIZE = 500; // for size*size matrix
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
int i,j,k;
double s;
/*
*
*/
int main(int argc, char** argv) {
double a[SIZE][SIZE], b[SIZE][SIZE], ans[SIZE][SIZE];
// assign the numbers for matrix a and b
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
a[i][j]=(double)rand()/RAND_MAX;
b[i][j]=(double)rand()/RAND_MAX;
}
}
MultiplyMatricesSequential(a,b,ans);
return 0;
}
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE])
{
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
for (k = 0; k < SIZE; k++)
s += a[i][k] * b[k][j];
ans[i][j] = s;
s = 0.0;
}
}
}
Upvotes: 0
Views: 854
Reputation: 2540
The bottom line is that although a 600-by-600 matrix is not that big, the stack memory limit (i.e. the limit for variables not allocated dynamically) is rather low (see for example here).
Upvotes: 0
Reputation:
First of all - if you're going to read some data with unknown size - I strongly recommend you using dynamic memory allocation for storing it instead of pre-allocating some fixed-size arrays. If this is not your case or you don't want to listen to my advice then better allocate those bigger arrays in the global namespace instead on the stack. This means that your code will look something like that:
using namespace std;
const int SIZE = 500; // for size*size matrix
void MultiplyMatricesSequential(double a[][SIZE],double b[][SIZE],double ans[][SIZE]);
int i,j,k;
double s;
/*
*
*/
double g_a[SIZE][SIZE], g_b[SIZE][SIZE], g_ans[SIZE][SIZE];
int main(int argc, char** argv) {
// assign the numbers for matrix a and b
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
g_a[i][j]=(double)rand()/RAND_MAX;
g_b[i][j]=(double)rand()/RAND_MAX;
}
}
MultiplyMatricesSequential(g_a,g_b,g_ans);
return 0;
}
//..........
Note that I added a "g_" prefix to your "matrices" names.
Also know that the stack or the "local storage" is used for storing temporary variables and function arguments which will be allocated to it when the function in which they belong to is called and "removed" when it returns. However the stack size is fixed and if there is no space in it to create them the program crashes. Global variables on the other hand doesn't have a memory limit as the space they need is automatically allocated on compile-time. Their life-time equals the application run-time as your "matrices" does because you had created them into the "main" function. So the choice now is simple - do you want to waste program time allocating & "removing" data and also risking a stack overflow or get your big data without a hassle - using global variables. Or if using real data - becoming friendlier with dynamic memory allocation.
Upvotes: 2