0

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;
                }

            }


        }
prime
  • 14,464
  • 14
  • 99
  • 131
  • I'm guessing you ran out of memory. – duffymo Sep 19 '14 at 20:56
  • So can't I multiply 2 matrices with size 600*600 :( – prime Sep 19 '14 at 20:57
  • You can't declare three 600x600 `double` arrays on the stack (automatic storage). – Blastfurnace Sep 19 '14 at 20:59
  • Don't know. I'd cut & paste that error into Google to see what it tells you. (600*600 double)*(8 bytes/double) ~ 2.8MB. Not that big. You'll have two matricies and the result, so multiply by 3. Still not that much memory. How much do you have on your machine? – duffymo Sep 19 '14 at 21:00

2 Answers2

2

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.

0

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).

Community
  • 1
  • 1
Emerald Weapon
  • 2,392
  • 18
  • 29