--- Dave Korn <[EMAIL PROTECTED]> wrote:

> On 30 March 2006 14:34, Pete wrote:
> 
> > The executable is produced with:
> > 
> > $ make
> > g++ -W -Wall -O9 -funroll-loops -mtune=pentium4  
> -c
> > -o matrix_mult_r.o matrix_mult_r.cc
> 
>   Heh.
> 
> 
> matrix_mult_r.cc:5:19: Timer.h: No such file or
> directory
> matrix_mult_r.cc: In function `int main()':
> matrix_mult_r.cc:20: error: `Timer' undeclared
> (first use this function)
> matrix_mult_r.cc:20: error: (Each undeclared
> identifier is reported only once
> for each function it appears in.)
> matrix_mult_r.cc:20: error: expected `;' before
> "timer"
> matrix_mult_r.cc:21: error: `timer' undeclared
> (first use this function)

ok... ok... :)

Attaching the files to the email.  Hope attachments
are OK.

> However, it's straightforward enough.  The default
> thread stack is 1Mb (or
> is it 2, I can't remember off the top of my head). 
> Once your stack-based auto
> vars exceed the size of the stack, it go BOOOOOM!

But doesn't the implementation keep track of stack
allocations?  Why let the hardware report a SIGSEGV
rather than let libc report "Out of memory" and
killing the process?

>   Your problem can be fixed /either/ by making them
> of static storage duration
> (move them out of the function body OR add the
> 'static' qualifier depending on
> scoping considerations),

Trying to learn...   Is that because if I declare the
variables as static (or make them global), they're
placed in the "data segment" and the compiler
automatically allocates enough space for them?

> or by using the -Wl,--stack
> flag.  Correctly.  You
> told ld to provide an 8kB stack.  Try 80 meg
> instead, it works a lot beter!

Yes, that definitely did the trick.  Thanks!  I think
the FAQ should be expanded a bit on the subject (I'd
be willing to write and submit if there's noone
designated as FAQ maintainer).

One last issue.  I was replying to one of your earlier
emails about using GDB.  For some reason, no matter
what I do, GDB always segfaults when I run the program
under GDB.

For a nice small eigensystem (N=200, ITERATIONS=2000):

$ make
g++ -W -Wall -O9 -funroll-loops -mtune=pentium4 -g  
-c -o matrix_mult_r.o matrix_mult_r.cc
g++ -W -Wall -O9 -funroll-loops -mtune=pentium4 -g  
-c -o Timer.o Timer.cc
g++ -Wl,--heap,8192,--stack,83886080 -o
matrix_mult_r.exe *.o
$ gdb matrix_mult_r.exe

(gdb) break 1
Breakpoint 1 at 0x401220: file matrix_mult_r.cc, line
1.
(gdb) run

Breakpoint 1, main () at matrix_mult_r.cc:16
16      {
(gdb) n
0x004101f0 in _alloca ()
(gdb) n
Single stepping until exit from function _alloca,
which has no line number information.
0x004101f6 in probe ()
(gdb) n
Single stepping until exit from function probe,
which has no line number information.
0x0041020d in done ()
(gdb) n
Single stepping until exit from function done,
which has no line number information.
main () at matrix_mult_r.cc:16
16      {
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x610ae938 in pthread_key_create () from
/usr/bin/cygwin1.dll


I use GDB quite a bit, and would _really_ like to be
able to use in on Cygwin.  The problem isn't even with
my benchmarking code.  Even with a hello world
program:

#include <iostream>
using namespace std;

int main( void )
{
   cout << "hello world" << endl;

   return 0;
}

when compiled with:

$ g++ -g  foo.cc

produces a segfault under GDB:

$ gdb -quiet a.exe
(gdb) break 1
Breakpoint 1 at 0x401150: file foo.cc, line 1.
(gdb) run

Breakpoint 1, main () at foo.cc:6
6       {
(gdb) n
0x0040f400 in _alloca () at
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/iostream:77
77        static ios_base::Init __ioinit;
(gdb) n
main () at foo.cc:6
6       {
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x610ae938 in pthread_key_create () from
/usr/bin/cygwin1.dll

Also, I noticed from my benchmark code that GDB
reports that it's in libc (or whatever!) functions
like alloca().  Is there a way to surpress mention of
any stepping into functions that don't have debugging
information?

Thanks again,
Pete

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Attachment: Makefile
Description: 402397780-Makefile

#define  N           600   // The dimension of the matrices
#define  ITERATIONS 2000   // Number of times to perform multiplication.

#include "Timer.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static void complain_and_die( void );
static int  getInt( const int low, const int high );
static void fill_matrix( int m[][N] );
static void matrix_multiplication( const int a[][N], const int b[][N], int 
result[][N] );



int main( void )
{
        // Set up the timer and start it ticking.
        Timer timer;
        timer.startTimer();

        // We multiply m1 and m2, and put the result in m3.
        int m1[N][N];
        int m2[N][N];
        int m3[N][N];

        // Seed the random number generator
        srand( time(NULL) );

        // Perform the multiplication ITERATIONS times.
        for ( int i = 0; i < ITERATIONS; ++i )
        {
                fill_matrix( m1 );
                fill_matrix( m2 );
                matrix_multiplication( m1, m2, m3 );
        }

        // Stop the timer and end the program.
        timer.endTimer();
        timer.printStats();
        return 0;
}



inline static void complain_and_die( void )
{
        fprintf( stderr, "I need the rank of the matrix\n" );
        exit(1);
}



inline static int getInt( const int low, const int high )
{
        return low + ( rand() % (high - low + 1) );
}



inline static void fill_matrix( int m[][N] )
{
        for ( int i = 0; i < N; ++i )
                for ( int j = 0; j < N; ++j )
                        m[i][j] = getInt(0, 100);
}



inline static void matrix_multiplication( const int a[][N], const int b[][N], 
int result[][N] )
{
        for( int i = 0; i < N; ++i )
                for( int j = 0; j < 3; ++j )
                        for( int k = 0; k < N ; ++k )
                                result[i][j] = a[i][k] + b[k][j];
}
#include <iostream>
#include <iomanip>
#include "Timer.h"
using namespace std;



Timer::Timer()
{
}



Timer::~Timer()
{
}



void Timer::startTimer( void )
{
        gettimeofday(&t_start, NULL);
        this->start = t_start.tv_sec + t_start.tv_usec * 
SECONDS_PER_MICROSECOND;
}



void Timer::endTimer( void )
{
        gettimeofday(&t_end, NULL);
        this->end = t_end.tv_sec + t_end.tv_usec * SECONDS_PER_MICROSECOND;
}



double Timer::getTimeInSeconds( void )
{
        return this->end - this->start;
}



// In seconds since the epoch.
//
double Timer::getStartTime( void )
{
        return this->start;
}



// In seconds since the epoch.
//
double Timer::getEndTime( void )
{
        return this->end;
}



void Timer::printStats( void )
{
        streamsize prec = cout.precision();
        cout << setprecision(12) << endl << "Timing Stats:" << endl;
        // cout << "End:   " << this->end << " seconds" << endl;
        // cout << "Start: " << this->start << " seconds" << endl;
        cout << "Total: " << this->getTimeInSeconds() << " seconds" << endl;
        cout << setprecision(prec);   // be polite.
}
#ifndef TIMER_H
#define TIMER_H

#include <sys/time.h>
#define SECONDS_PER_MICROSECOND 1.0E-6L;

class Timer
{
        private:
                timeval t_start, t_end;
                double  start, end;

        public:
                Timer::Timer();
                Timer::~Timer();
                void   Timer::startTimer( void );
                void   Timer::endTimer( void );
                double Timer::getTimeInSeconds( void );
                double Timer::getStartTime( void );
                double Timer::getEndTime( void );
                void   Timer::printStats( void );
};

#endif

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to