Thread: need help for this program plz

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    2

    need help for this program plz

    Code:
    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<pthread.h>
    #define INPUT_NEURONS 256
    #define HIDDEN_NEURONS 150
    #define OUTPUT_NEURONS 10
    #define CONTEXT_NEURONS 150
    #define no_of_clients 10
    #define no_trng_vectors 1593
    int HIDDENNEURONS = HIDDEN_NEURONS/no_of_clients;
    // Activations.
    double inputs[INPUT_NEURONS];
    double hidden[HIDDEN_NEURONS]={0};
    double target[OUTPUT_NEURONS];
    double actual[OUTPUT_NEURONS];
    double context[CONTEXT_NEURONS]={0};
    static double outputs_from_file[no_trng_vectors][OUTPUT_NEURONS];
    static double inputs_from_file[no_trng_vectors][INPUT_NEURONS];
    
    
    double batch_deltawho[no_trng_vectors][INPUT_NEURONS][OUTPUT_NEURONS];
    double batch_deltawih[no_trng_vectors][INPUT_NEURONS][HIDDEN_NEURONS];
    double batch_erro[no_trng_vectors][OUTPUT_NEURONS];
    
    
    typedef struct{
        
        int cli_index;
        
        int sam;
    }cli_var;
         
    
    
    double temp = 0.0;    
    int itteration;
    int stop = 0;
    double LEARN_RATE = 0.2;    // Rho.
    //-------------------------------------------------------------
    // Input to Hidden Weights (with Bias es).
    //double wih[INPUT_NEURONS][HIDDEN_NEURONS]={{0.840188,0.394383,0.783099},{0.798440,0.911647,0.197551},{0.335223,0.768230,0.277775},{0.553970,0.477397,0.628871},{0.364784,0.513401,0.952230},{0.916195,0.635712,0.717297}
    
    
    // Context to Hidden Weight (with Biases).
    //double wch[CONTEXT_NEURONS][HIDDEN_NEURONS]={{0.141603,0.606969,0.016301},{0.242887,0.137232,0.804177},{0.156679,0.400944,0.129790}
    
    
    
    
    
    
    // Hidden to Output Weights (with Biases).
    //double who[HIDDEN_NEURONS][OUTPUT_NEURONS]={{0.108809,0.998925,0.218257,0.512932,0.839112,0.612640},{0.296032,0.637552,0.524287,0.493583,0.972775,0.292517},{0.771358,0.526745,0.769914,0.400229,0.891529,0.283315}};
    double wih[INPUT_NEURONS][HIDDEN_NEURONS];
    double wch[CONTEXT_NEURONS][HIDDEN_NEURONS];
    double who[HIDDEN_NEURONS][OUTPUT_NEURONS];
    // Hidden to Context Weights (no Biases).
    double whc[OUTPUT_NEURONS][CONTEXT_NEURONS];
                                                                   
    
    
    // Unit errors.
    double erro[OUTPUT_NEURONS];
    double errh[HIDDEN_NEURONS];
    
    
    int NUM_THREADS=no_of_clients+1;
        pthread_t threads[11];
    int a[2]={0,0};
    double fRand(double,double);
    double sigmoid(double);
    double sigmoidDerivative(double);
    void backPropagate();
    void assignRandomWeightsIH();
    void assignRandomWeightsCH();
    void assignRandomWeightsHC();    
    void assignRandomWeightsHO();
    void storeError(int);
    void elmanNetwork();
    void *server(void *);
    void *client(void *);
    
    
    main()
    { 
        int noofinp=0,noofout=0;
        struct timeval tv1,tv2;
        int hid,out;
        unsigned long long  startingtime,endingtime;
        gettimeofday(&tv1,NULL);
        startingtime=tv1.tv_usec + tv1.tv_sec *1000000;
        printf("starting time in seconds:");
        printf("%llu",startingtime);
        FILE *fp;
        int i,l,k;
        fp=fopen("read.txt","r");
        
        /*fscanf(fp,"%d",&INPUT_NEURONS);
        
        fscanf(fp,"%d",&HIDDEN_NEURONS);
        
        fscanf(fp,"%d",&CONTEXT_NEURONS);
        
        fscanf(fp,"%d",&OUTPUT_NEURONS); */
        
        fscanf(fp,"%lf",&LEARN_RATE);
        
        //fscanf(fp,"%d",&no_trng_vectors); 
        
        /*for(i=0;i<no_trng_vectors;i++)
        
        {     
        
            for (l = 0; l < INPUT_NEURONS; l++){
                fscanf (fp, "%lf", &inputs_from_file[i][l]);
                //printf("----%lf",inputs_from_file[i][l]);
            } 
            printf("\n");
    
    
    
    
          
            for (k = 0; k<OUTPUT_NEURONS; k++){
                fscanf (fp, "%lf", &outputs_from_file[i][k]);
            }
        }*/
        for(i=0,noofinp=0,noofout=0;i<no_trng_vectors;i++)
        {     
               for (l = 0; l < INPUT_NEURONS; l++)
               {
            if(noofinp!=256)
            {
            fscanf (fp, "%lf", &inputs_from_file[i][l]);
            noofinp++;
            }
            //printf("----%lf",inputs_from_file[i][l]);
               } 
    
    
    
    
                   for(k = 0; k<OUTPUT_NEURONS; k++)
               {
            if(noofout!=10)
            {
            fscanf (fp, "%lf", &outputs_from_file[i][k]);
                noofout++;            
                    }
            } 
            }
        
    
    
    /*for(i=0;i<no_trng_vectors;i++) //accepting inputs nd outputs from file
        
        {     
        
            for (l = 0; l < INPUT_NEURONS; l++){
                
                printf("inputs----%lf",inputs_from_file[i][l]);
                printf("\t");
            } 
            printf("\n");
    
    
    
    
          
            for (k = 0; k<OUTPUT_NEURONS; k++){
                printf ("outputs----%lf", outputs_from_file[i][k]);
                printf("\t");
            }
            printf("\n");
        }*/ 
        
    
    
        fclose(fp);
            assignRandomWeightsHC();    
            assignRandomWeightsHO();
            assignRandomWeightsIH();
            assignRandomWeightsCH();
            elmanNetwork();
        printf("\nnetwork is trained at %lf",temp);
         
        /*for(out = 0; out < OUTPUT_NEURONS; out++)
        {
            for(hid = 0; hid < HIDDEN_NEURONS; hid++)
            {
            //printf("%lf", who[hid][out]);
            //printf("...........");        
            }
         }*/
        
        
        gettimeofday(&tv2,NULL);
            endingtime=tv2.tv_usec + tv2.tv_sec *1000000;
            printf("\nendingtime:%llu",endingtime);
    if(startingtime<endingtime)
            printf("\ntime taken in parallel code using pthreads:%llu\n",(endingtime-startingtime));
    else
            printf("\ntime taken in parallel code using pthreads:%llu\n",(startingtime-endingtime));
    }
    
    
    
    
    void elmanNetwork()
    {
        int i,j,cli_index;
        int inp,out;
        int batch_count=0;
            cli_var cli_val1;
        while(!stop)
        {
         int sample=0;
         batch_count++;
            /*if(batch_count==60){
                break;
            }*/
        for(j=0;j<no_trng_vectors;j++)
        {
         for(inp=0;inp<INPUT_NEURONS;inp++)
          {
           inputs[inp]=inputs_from_file[sample][inp];                
           //printf("-------%lf",inputs[inp]);                
          }                
          for(out=0;out<OUTPUT_NEURONS;out++)
          {
           target[out]=outputs_from_file[sample][out];
          }// creating client thread.
          /*for(i=0,cli_val1.cli_index=0;i<NUM_THREADS-1;i++,cli_val1.cli_index++)
          {
            pthread_create(&threads[i],NULL,client,(void *)&cli_val1);
            //pthread_join(threads[i],NULL);
           }*/
           //printf(".......");
           // creating server thread.
           pthread_create(&threads[0],NULL,server,(void *)sample);
           pthread_join(threads[0],NULL);
           //a[0]=0;
           //a[1]=0;
           sample++;
        }
        //printf("\n batch_count:%d",batch_count);
        }
        
        return;
    }
    
    
    void *client(void * index)
    {
        cli_var *cli_var2;
        cli_var2=(cli_var*)index;    
        int con;
        double sum = 0.0;
        int hid,inp,out;
        //printf("\n inside client,index %d", cli_var2->cli_index);
        int sample=cli_var2->sam;
        /*for(inp=0;inp<INPUT_NEURONS;inp++)
        {
        inputs[inp]=inputs_from_file[sample][inp];
        //printf("-------%lf",inputs[inp]);
        }
        for(out=0;out<OUTPUT_NEURONS;out++)
        {
        target[out]=outputs_from_file[sample][out];
        }*/
        // calculate inputs to hidden layer using wih & wch
        // part of feed forward 
            for(hid = (cli_var2->cli_index)*HIDDENNEURONS; hid < ((cli_var2->cli_index)+1)*HIDDENNEURONS; hid++)
            {
                sum = 0.0;
                for(inp = 0; inp < INPUT_NEURONS; inp++)    // from input to hidden...
                {
                    sum += inputs[inp] * wih[inp][hid];
                    //printf("\n sum: %lf",sum);
                } // inp
                
                for(con = 0; con < CONTEXT_NEURONS; con++)    // from context to hidden...
                {
                    sum += context[con] * wch[con][hid];
                    //printf("\n sum with con: %lf",sum);
                } // con
                
                //sum += wih[INPUT_NEURONS][hid];    // Add in bias.
                //sum += wch[CONTEXT_NEURONS][hid];
                hidden[hid] = sigmoid(sum);
            } // hid
        //a[cli_var2->cli_index]=1;
    }
    
    
    void assignRandomWeightsIH()
    {
        int inp,hid;
        for(inp = 0; inp < INPUT_NEURONS; inp++)    // Do not subtract 1 here.
        {
            for(hid = 0; hid <HIDDEN_NEURONS; hid++)
            {
                // Assign a random weight value between 0 and 1
                wih[inp][hid] = fRand(0,1);
            //printf("wih:%lf",wih[inp][hid]);
            } // hid
            //printf("\n");
        } // inp
        return;
    }
    
    
    void assignRandomWeightsCH()
    {
        int con,hid;
        for(con = 0; con < CONTEXT_NEURONS; con++)
        {
            for(hid = 0; hid <HIDDEN_NEURONS; hid++)
            {
                // Assign a random weight value between 0 and 1
                wch[con][hid] = fRand(0,1);
            //printf("wch:%lf",wch[con][hid]);
            } // hid
            //printf("\n");
        } // con
        return;
    }
    
    
    
    
    void *server(void *index)
    {
        double err;
        double sum;
        cli_var cli_val1;
        int sample=(int)index;    
        int out,hid,con,count,inp;
        
        int i,l,j;    
        
        cli_val1.sam=sample;
        //printf("\n inside server,index %d", cli_var2->cli_index);
        //printf("\n inside server,sample %d", sample);
        
        for(i=1,cli_val1.cli_index=0;i<NUM_THREADS;i++,cli_val1.cli_index++)
                {
                    //printf("client index %d",cli_val1.cli_index);
                    pthread_create(&threads[i],NULL,client,(void *)&cli_val1);
                    //pthread_join(threads[i],NULL);
                }
            pthread_join(threads[i-1],NULL);
            /*if(!(a[0]&&a[1]))
            {
                printf("sleeping");            
                sleep(10);
            }*/
            
    
    
        //while(1){
        
            //while(sample!=no_trng_vectors){    
           // Train the network.
               //itteration++;
            // Calculate the  hidden to output layer.
        // part of feed forward
            for(hid = 0; hid < HIDDEN_NEURONS; hid++){
            //printf("hidden: %lf",hidden[hid]);
        }
            for(out = 0; out < OUTPUT_NEURONS; out++)
            {
                sum = 0.0;
                for(hid = 0; hid < HIDDEN_NEURONS; hid++)
                {
                    sum += hidden[hid] * who[hid][out];
                } // hid
    
    
                //sum += who[HIDDEN_NEURONS][out];    // Add in bias.
                actual[out] = sigmoid(sum);
            } // out
    
    
    
    
         // Copy outputs of the hidden to context layer.
            for(con = 0; con < CONTEXT_NEURONS; con++)
            {
                context[con] = hidden[con];
            }                        
            storeError(sample);
            //sample++;
    
    
        
        //}
      
                
            if(sample==no_trng_vectors-1){
                err = 0.0;
                for(j=0; j < no_trng_vectors; j++){
                    for(i = 0; i < OUTPUT_NEURONS; i++)
                    {
                        //err += Math.sqrt(target_vector[i] - output_vector[i]);
                        err += batch_erro[j][i]*batch_erro[j][i];
                    }
                }
                err = 0.5 * err/no_trng_vectors;
                //printf("err:%lf",err);
            
                if(temp>0.0){
                    if(temp-err>0.2){
                        LEARN_RATE=LEARN_RATE-LEARN_RATE*0.1;
                    
                    }else if(temp-err<0.2){
                        LEARN_RATE=LEARN_RATE+LEARN_RATE*0.1;
                    }
                }
                temp=err;
                if(err<0.05)
                {
                    stop = 1;
                    //printf(".....%lf....",err);
                
                    //break;
        
                }
                else{
             
                    backPropagate();
                    //sample=0;
                    itteration++;
                    return;
    
    
                }
            }
        
        //}
    
    
           
        //printf("itterations :%d",itteration);
        
            return;    
    }
    
    
    void assignRandomWeightsHC()
    {
        int con,out;    
        for(out = 0; out < OUTPUT_NEURONS; out++)
        {
            for(con = 0; con < CONTEXT_NEURONS; con++)
            {
                // These are all fixed weights set to 0.5
                whc[out][con] = 0.5;
            } // con
        } //  out
        return;
    }
    
    
    void assignRandomWeightsHO()
    {
        int hid,out;    
        for(hid = 0; hid < HIDDEN_NEURONS; hid++)    //Do not subtract 1 here.
        {
            for(out = 0; out < OUTPUT_NEURONS; out++)
            {
                // Assign a random weight value between 0 and 1
                who[hid][out] = fRand(0,1);
            //printf("who:%lf",who[hid][out]);
            } // out
            //printf("\n");
    
    
        } // hid
        return;
    }
    
    
    void storeError(int trng_vector_index)
    {
        int count1=0;
        int out,hid,inp;
        int i;    
        //printf("\n storing error for trngvectorind %d ",trng_vector_index);
        // Calculate the output layer error (step 3 for output cell).
        for(out = 0; out < OUTPUT_NEURONS; out++)
        {
            batch_erro[trng_vector_index][out] =  (target[out] - actual[out]);
            erro[out] = (target[out] - actual[out]) * sigmoidDerivative(actual[out]);
        }
          
        // Calculate the hidden layer error and updating (step 3 for hidden cell).
        for(hid = 0; hid < HIDDEN_NEURONS; hid++)
        {
            errh[hid] = 0.0;
            for(out = 0; out < OUTPUT_NEURONS; out++)
            {
                errh[hid] += erro[out] * who[hid][out];
            } // out
            errh[hid] *= sigmoidDerivative(hidden[hid]);
        } // hid
    
    
        // Update the weights for the output layer (step 4).
        for(out = 0; out < OUTPUT_NEURONS; out++)
        {
            for(hid = 0; hid < HIDDEN_NEURONS; hid++)
            {
                batch_deltawho[trng_vector_index][hid][out] += (LEARN_RATE * erro[out] * hidden[hid]);
                //who[hid][out] += (LEARN_RATE * erro[out] * hidden[hid]);
            } // hid
            
            //who[HIDDEN_NEURONS][out] += (LEARN_RATE * erro[out]);    // Update the bias.
        } // out
    
    
        // Update the weights for the hidden layer (step 4).
        for(hid = 0; hid < HIDDEN_NEURONS; hid++)
        {
            for(inp = 0; inp < INPUT_NEURONS; inp++)
            {
                batch_deltawih[trng_vector_index][inp][hid] += (LEARN_RATE * errh[hid] * inputs[inp]);
                //wih[inp][hid] += (LEARN_RATE * errh[hid] * inputs[inp]);
            } // inp
            
            //wih[INPUT_NEURONS][hid] += (LEARN_RATE * errh[hid]);    // Update the bias.
        } // hid
    
    
    }    
    
    
    
    
    
    
     void backPropagate()
     {
         int count1=0;
         int out,hid,inp;
         int trng_vector_ind;
         int i;    
         
            // Calculate the output layer error (step 3 for output cell).
            for(out = 0; out < OUTPUT_NEURONS; out++)
            {     
         erro[out] = (target[out] - actual[out]) * sigmoidDerivative(actual[out]);
        }   
            // Calculate the hidden layer error and updating (step 3 for hidden cell).
            for(hid = 0; hid < HIDDEN_NEURONS; hid++)
        {
         errh[hid] = 0.0;
         for(out = 0; out < OUTPUT_NEURONS; out++)
         {               
            errh[hid] += erro[out] * who[hid][out];
         } // out
          errh[hid] *= sigmoidDerivative(hidden[hid]);
        } // hid
        
    
    
            // Update the weights for the output layer (step 4).
            for(out = 0; out < OUTPUT_NEURONS; out++)
        {
            for(hid = 0; hid < HIDDEN_NEURONS; hid++)
            {        
                for(trng_vector_ind =0; trng_vector_ind<no_trng_vectors; trng_vector_ind++){
                                who[hid][out] += batch_deltawho[trng_vector_ind][hid][out];
                            
                    }
                who[hid][out]=who[hid][out]/no_trng_vectors;    
                      //who[hid][out] += (LEARN_RATE * erro[out] * hidden[hid]);
            } // hid
            //who[HIDDEN_NEURONS][out] += (LEARN_RATE * erro[out]);    // Update the bias.
        } // out
        
    
    
            // Update the weights for the hidden layer (step 4).
            for(hid = 0; hid < HIDDEN_NEURONS; hid++)
        {
            for(inp = 0; inp < INPUT_NEURONS; inp++)
            {        
                for(trng_vector_ind =0; trng_vector_ind<no_trng_vectors; trng_vector_ind++){
                                wih[inp][hid] += batch_deltawih[trng_vector_ind][inp][hid];
                            }
                    
                wih[inp][hid]=wih[inp][hid]/no_trng_vectors;    
                //wih[inp][hid] += (LEARN_RATE * errh[hid] * inputs[inp]);
            } // inp
            
            //wih[INPUT_NEURONS][hid] += (LEARN_RATE * errh[hid]);    // Update the bias.
        } // hid
    }    
    
    
    double fRand(double fMin, double fMax)
    {
        double f = (double)rand()/ RAND_MAX;
        return fMin + f * (fMax - fMin);
    }
        
    double sigmoid(double val)
    {
        return (1.0 / (1.0 +exp(-val)));
    }
    
    
    double sigmoidDerivative(double val)
    {
        return (val * (1.0 - val));
    }























    this program is used to read the processor time.......................


    this program has 2 b compiled in linux

    when i compile this program in ubuntu it says "segmentation error"

    Plz help me out!!!!




    Thanks in advance.......

  2. #2
    Registered User
    Join Date
    Sep 2012
    Posts
    2
    plz help me..... it's my project

  3. #3
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by ramesh333 View Post
    this program is used to read the processor time.......................
    No, it is not. It is an attempt at neural network simulation.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    1. We can't do anything with the code without the input data file as well. Nobody is going to look through 600+ lines of code just for the fun of it.

    2. You really need to fix your warnings.
    Code:
    $ gcc -g -Wall foo.c -pthread -lm
    foo.c:85:1: warning: return type defaults to ‘int’ [-Wreturn-type]
    foo.c: In function ‘main’:
    foo.c:91:5: warning: implicit declaration of function ‘gettimeofday’ [-Wimplicit-function-declaration]
    foo.c:89:13: warning: unused variable ‘out’ [-Wunused-variable]
    foo.c:89:9: warning: unused variable ‘hid’ [-Wunused-variable]
    foo.c: In function ‘elmanNetwork’:
    foo.c:241:47: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
    foo.c:215:17: warning: unused variable ‘cli_val1’ [-Wunused-variable]
    foo.c:212:13: warning: unused variable ‘cli_index’ [-Wunused-variable]
    foo.c:212:9: warning: unused variable ‘i’ [-Wunused-variable]
    foo.c: In function ‘client’:
    foo.c:262:9: warning: unused variable ‘sample’ [-Wunused-variable]
    foo.c:260:17: warning: unused variable ‘out’ [-Wunused-variable]
    foo.c: In function ‘server’:
    foo.c:338:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    foo.c:435:17: warning: ‘return’ with no value, in function returning non-void [-Wreturn-type]
    foo.c:447:9: warning: ‘return’ with no value, in function returning non-void [-Wreturn-type]
    foo.c:341:11: warning: unused variable ‘l’ [-Wunused-variable]
    foo.c:339:27: warning: unused variable ‘inp’ [-Wunused-variable]
    foo.c:339:21: warning: unused variable ‘count’ [-Wunused-variable]
    foo.c: In function ‘storeError’:
    foo.c:489:9: warning: unused variable ‘i’ [-Wunused-variable]
    foo.c:487:9: warning: unused variable ‘count1’ [-Wunused-variable]
    foo.c: In function ‘backPropagate’:
    foo.c:548:10: warning: unused variable ‘i’ [-Wunused-variable]
    foo.c:545:10: warning: unused variable ‘count1’ [-Wunused-variable]
    foo.c: In function ‘client’:
    foo.c:294:1: warning: control reaches end of non-void function [-Wreturn-type]
    foo.c: In function ‘main’:
    foo.c:205:1: warning: control reaches end of non-void function [-Wreturn-type]
    Now some of this might be down to the hatchet job you've done on the code, trying to comment out the bug.

    3. Notice the -g in the compilation line
    Now do this.
    Code:
    $ gdb ./a.out 
    GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
    Copyright (C) 2011 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    For bug reporting instructions, please see:
    <http://bugs.launchpad.net/gdb-linaro/>...
    Reading symbols from /home/sc/Documents/a.out...done.
    (gdb) run
    Starting program: /home/sc/Documents/a.out 
    [Thread debugging using libthread_db enabled]
    
    Program received signal SIGSEGV, Segmentation fault.
    __isoc99_fscanf (stream=0x0, format=0x4019da "%lf") at isoc99_fscanf.c:31
    31	isoc99_fscanf.c: No such file or directory.
    	in isoc99_fscanf.c
    (gdb) bt
    #0  __isoc99_fscanf (stream=0x0, format=0x4019da "%lf") at isoc99_fscanf.c:31
    #1  0x0000000000400898 in main () at foo.c:107
    (gdb)
    Now my segfault is due to me not having the input file, and you NOT checking whether the input file was opened successfully.

    When you try and run the code in the debugger, chances are it will segfault somewhere else.
    Your next post should at least be the 'bt' of where the code crashed when you run it.

    Not that you should post it immediately, spend some time thinking about where it got to in the code.
    If it seems to be indexing an array, try examining the array subscripts to see if they're valid.

    4. By the time you get to writing threaded code, you should be competent enough to write single threaded code AND use the debugger to help you fix your own code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Quote Originally Posted by Nominal Animal View Post
    No, it is not. It is an attempt at neural network simulation.
    No kidding, huh? Very, very strange.

    And it's cross-posted.

  6. #6
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by rags_to_riches View Post
    No kidding, huh?
    I should've emphasized the "an attempt" bit in my post. It is really strange.

    In a blind effort to be helpful, here is the method I use to measure the CPU and wall clock time used by a program or a function using POSIX C:

    First, you'll need four struct timespec variables, and optionally two doubles to store the number of seconds:
    Code:
    #define _POSIX_C_SOURCE 199309L
    #include <time.h>
    
    struct timespec cpu_started, cpu_stopped;
    struct timespec wall_started, wall_stopped;
    double cpu_seconds, wall_seconds;
    To start the timing measurement, use
    Code:
    clock_gettime(CLOCK_REALTIME, &wall_started);
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_started);
    and to finish, use
    Code:
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_stopped);
    clock_gettime(CLOCK_REALTIME, &wall_stopped);
    cpu_seconds = (double)(cpu_stopped.tv_sec - cpu_started.tv_sec)
                 + (double)(cpu_stopped.tv_nsec - cpu_started.tv_nsec) / 1000000000.0;
    wall_seconds = (double)(wall_stopped.tv_sec - wall_started.tv_sec)
                  + (double)(wall_stopped.tv_nsec - wall_started.tv_nsec) / 1000000000.0;
    Second, you'll want to put the measurable code in a separate compilation unit -- basically, a separate function in a separate file --, so that you can compile and link it separately from the timing "chassis", without compiler optimizations getting in the way.

    Third, if the function is short, you can estimate the function call overhead by doing a copy of the measured function but with an empty body, and measuring that too. The function call overhead is typically just dozens to maybe a couple of hundred CPU cycles, so for any function that runs for more than a millisecond or so the function call overhead will be irrelevant.

    Fourth, you'll want to repeat the measurement, and ignore any outliers. There are cases when the CPU time is bogus (for example when migrating between CPU cores), and when the wall clock is bogus (for example, when an NTP adjustment occurs). Do a repeated test, ignore say 10% of the longest durations (because they are artefacts of the measurement; inaccuracies due to measurement), and look at the distribution of the rest of the values. Usually you'll see them clustered very heavily at the short duration end -- unless you use I/O, in which case the results depend heavily on caching, disk type (rotating or SSD), and other details completely outside the control of the measured process. If you have outliers in the short duration end too, ignore those too. I normally look at the median (the durations where half of the measurements are longer, and half shorter); it gives a rather reliable answer: "half the time the function will take X seconds or less".

    Fifth, if you are using GCC on x86 or x86-64, you can use the TSC (CPU core cycle counter) directly. (In Linux at least the above method does use TSC; I personally just like to see the cycle values instead of CPU time in seconds.) Using the TSC directly:
    Code:
    #define _POSIX_C_SOURCE 199309L
    #include <time.h>
    #include <stdint.h>
    
    struct timespec wall_started, wall_stopped;
    uint64_t cpu_started, cpu_stopped;
    double cpu_cycles, wall_seconds;
    
    clock_gettime(CLOCK_REALTIME, &wall_started);
    cpu_started = __builtin_ia32_rdtsc();
    
    /* Measurement loop */
    
    cpu_stopped = __builtin_ia32_rdtsc();
    clock_gettime(CLOCK_REALTIME, &wall_stopped);
    
    cpu_cycles = (double)(cpu_stopped - cpu_started);
    wall_seconds = (double)(wall_stopped.tv_sec - wall_started.tv_sec)
                  + (double)(wall_stopped.tv_nsec - wall_started.tv_nsec) / 1000000000.0;
    There are further tricks to make the measurement more reliable -- for example, scattering any array parameters in memory, to see how alignment/non-alignment affects the timing; not measuring the function the first time it is called with given parameters to make sure the cache is "hot"; doing un-measured memory-intensive work between test runs to make sure the cache is "cold"; and so on.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 07-14-2012, 09:43 AM
  2. Replies: 1
    Last Post: 03-03-2009, 04:47 PM
  3. Replies: 5
    Last Post: 08-16-2007, 11:43 PM
  4. Replies: 18
    Last Post: 11-13-2006, 01:11 PM
  5. making a program leave a msg for background program when it closes
    By superflygizmo in forum Windows Programming
    Replies: 2
    Last Post: 02-06-2006, 07:44 PM