Help to optimize the function in C
I am working on a C function for speed optimizaion. Below Function is taking 3-5 sec of time to complete, I want to reduce the time. Can somebody consult/help with some tips on how to achieve the desired result.
Code:
FormatMatrixComp(double * matrix, int *nmat, int *nrow, int *ncol, int * comp_flag, int * idbaseMat, int * idtargetMat)
{
int i,j,k,p;
struct MG1G1_ * ptTargetMat; // will be used to point to target matrix depending on value of idtargetMat
// initialization of structures
// char * cpReadString = ( char * ) malloc ( 1024 ) ;
// char * cpFileName = ( char * ) malloc ( 1024 ) ;
char * cpFileName = NULL; // not needed in this version
FILE * fStream = NULL; // dummy file pointer
int nRow = 0;
int nColumn = 0;
int nComp = 0;
short tempMG1G1Created = 0;
static nrow_old = 0;
static firsttime = 1;
#ifdef PROFILE
clock_t start,finish;
double duration;
#endif
// memory allocation of structure (only if dimension changed since last call)
// all other temporary structures used within this function call
#ifdef PROFILE
if(firsttime) fprintf(profile_file, "routine: FormatMatrixComp\n");
if(firsttime) fprintf(profile_file, "-----------------------\n");
if(firsttime) fprintf(profile_file, "\n");
if(firsttime) start = clock();
#endif
// initialize ams structure to zero
for(nComp =0; nComp< tempAMSdata.nComp_d;++nComp)
{
for(i = 0; i < tempAMSdata.stpDcomp[nComp].nStrip ; ++i )
{
for(j = 0; j<10; ++j)
tempAMSdata.stpDcomp[nComp].fpProps[i][j] = 0;
}
for(i = 0; i < tempAMSdata.stpDcomp[nComp].nStrip ; ++i )
{
for(j = 0; j<3; ++j)
tempAMSdata.stpDcomp[nComp].fpCoords[i][j] = 0;
}
}
// loop over all matrices
for (p=0; p<*nmat; p++)
{
lpdata.nBalasts = *nrow;
if(*nrow != nrow_old)
{
// free memory allocated for structure in second and third dimension before reallocating first dimension
for(i = 0; i < nrow_old; ++i)
{
for(j = 0; j < 1; ++j )
free(lpdata.stBalast[i].lpBalastMatrix[j]);
free(lpdata.stBalast[i].lpBalastMatrix);
}
// reallocate structure with new dimensions
lpdata.stBalast = (struct balast_section *) realloc (lpdata.stBalast, sizeof (struct balast_section) * *nrow);
for(i = 0; i < *nrow; ++i){
lpdata.stBalast[i].lpBalastMatrix = ( double ** ) malloc ( sizeof ( double * ) * 1);
for(j = 0; j < 1; ++j )
{
lpdata.stBalast[i].lpBalastMatrix[j] = ( double * ) malloc ( sizeof ( double ) * 10) ;
for(k = 0 ; k < 10 ; ++k)
{
lpdata.stBalast[i].lpBalastMatrix[j][k] = 0; // initialize values to zero
}
}
}
// remember old dimensions
nrow_old = *nrow;
}
// storage of FORTRAN matrix
for (k=0; k<*ncol; k++)
{
for (i=0; i<*nrow; i++)
{
lpdata.stBalast[i].nRows = 1;
lpdata.stBalast[i].nColumns = *ncol;
lpdata.stBalast[i].lpBalastMatrix[0][k] = *(matrix++);
}
}
if( ! createLPams( cpFileName, &stGeoxData, &stG2SData,&lpdata,&tempAMSdata,comp_flag))
{
// printf( "\n\ file creation Failed..............\n" ) ;
// fputs( "\file creation Failed..............", fStream ) ;
}
else
{
// printf( "\ file creation successful..............\n" ) ;
// fputs( "\ file creation successful..............", fStream ) ;
LPAMSCreated =1;
}
if (LPAMSCreated==1)
{
// printf( "\ File creation is complete..............\n" ) ;
// fputs( "\ File creation is complete..........", fStream ) ;
}
(comp_flag++);
} // loop over all matrices
#ifdef PROFILE
if(firsttime) finish = clock();
if(firsttime) duration = (double)(finish - start) / CLOCKS_PER_SEC;
if(firsttime) fprintf(profile_file, "create structure:\t\t\t\t\t%8.4f\n", duration);
#endif
// Write file for validation purposes
/*********************************************************************/
/* CREATE MATRIX FROM STRUCTURE ... */
/*********************************************************************/
/********************************Processing Files Operation *****************************/
stReturn = GetOnesMetrixDouble( tempMG1G1.dbpMG1G1_data, tempMG1G1.nRow, tempMG1G1.nColumn, 0 ); // initialize tempMG1G1 to zero
#ifdef PROFILE
if(firsttime) start = clock();
#endif
if(0 == ProcessMatrixData( &stProjectSpace, &tempAMSdata,
&stGeoxData, &stMatrixdata, &stG2SData,&tempMG1G1, fStream ))
{
}
else
{
tempMG1G1Created =1;
stReturn = GetOnesMetrixDouble( stouttempMG1G1->dbpMG1G1_data, stouttempMG1G1->nRow,stouttempMG1G1->nColumn, 0 );
if(0 == ConvertToG1SixMatrix(&tempMG1G1, stouttempMG1G1))
{
stReturn = 0;
}
else{
stReturn = 1;
}
}
#ifdef PROFILE
if(firsttime) finish = clock();
if(firsttime) duration = (double)(finish - start) / CLOCKS_PER_SEC;
if(firsttime) fprintf(profile_file, "ProcessMatrixData:\t\t\t\t\t\t\t\t%8.4f\n", duration);
#endif
/***************************************************************************************/
/* MERGE CREATED MATRIX WITH BASE MATRIX TO CREATE TARGET MATRIX ... */
/***************************************************************************************/
#ifdef PROFILE
if(firsttime) start = clock();
#endif
// select target matrix according to value of switch idbaseMat
switch(*idtargetMat)
{
case OWE_ID:
ptTargetMat = &stoutMg1g1OWE;
break;
case ZFW_ID:
ptTargetMat = &stMg1g1ZFW;
break;
case CS_ID:
ptTargetMat = &stMg1g1CS;
break;
}
stReturn = GetOnesMetrixDouble( ptBaseMat->dbpMG1G1_data, ptBaseMat->nRow,ptBaseMat->nColumn, 0 );
// initialize structure to zero
// copy values of original baseMat to temporary baseMat container row by row to prevent mixing up of data in the merging process
// (which matrix to select as baseMat depends on value of input flag idbaseMat)
for(nRow =0;nRow<ptBaseMat->nRow;++nRow){
switch(*idbaseMat)
{
case OWE_ID:
memcpy(ptBaseMat->dbpMG1G1_data[nRow],stoutMg1g1OWE.dbpMG1G1_data[nRow],sizeof ( double ) * ptBaseMat->nColumn);
break;
case ZFW_ID:
memcpy(ptBaseMat->dbpMG1G1_data[nRow],stMg1g1ZFW.dbpMG1G1_data[nRow],sizeof ( double ) * ptBaseMat->nColumn);
break;
case CS_ID:
memcpy(ptBaseMat->dbpMG1G1_data[nRow],stMg1g1CS.dbpMG1G1_data[nRow],sizeof ( double ) * ptBaseMat->nColumn);
break;
}
}
// initialize values of target matrix and cg matrix to zero
stReturn = GetOnesMetrixDouble( ptTargetMat->dbpMG1G1_data, ptTargetMat->nRow,ptTargetMat->nColumn, 0 );
stReturn = GetOnesMetrixDouble(CGMatrix, ptTargetMat->nRow,3, 0 );
// merge created matrix with base matrix to create target matrix
if(0== MergeMatrices(ptBaseMat,stouttempMG1G1, &stGeoxData,ptTargetMat,CGMatrix))
{
stReturn = 0;
}
else
{
stReturn = 1;
}
#ifdef PROFILE
if(firsttime) finish = clock();
if(firsttime) duration = (double)(finish - start) / CLOCKS_PER_SEC;
if(firsttime) fprintf(profile_file, "merge matrices:\t\t\t\t\t\t\t\t\t%8.4f\n", duration);
#endif
#ifdef PROFILE
// close profile
if(firsttime) fclose(profile_file);
#endif
if(firsttime) firsttime = 0;
} // end of function
Tools I am using
Visual studio 2008
Windows XP
Thank you very much.