Pointerarithmetik, 1D Array schnell nach 2D formatieren



  • Hallo zusammen,

    auf ein externes Array wird mit Pointer zugegriffen. Ziel ist es das 1D Array, extern, via Pointer möglichst schnell in ein 2D Array ODER in einen 2D Pointer zu formatieren. Der Nachfolgende Lösungsansatz berücksichtigt erstmal Variante 1DArray-1DPointer-2DArray(CPU intensiv).
    Über Speichermapping geht das schneller, nur wie? Alternative wäre
    1DArray-1DPointer-2DPointer(nicht CPU Intensiv)

    Der nachfolgende Code ist voll lauffähig und demostriert das Problem.

    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char *argv[])
    {
        // Obligatorisch
        int max_i=2;
        int max_j=2;
        register int i,j;
    
        // Ein externes Array auf das nur mit Pointer zugegriffen werden kann (MATLAB)
        int nodirectaccess[]={3,5,7,2}; 
        // Der Pointer der darauf zugreift
        int *data;
        // Das Zielarray 2*2 Elemente soll aus 1*4 Elemente erstellt werden
        int ddarray[2][2]={0};
    
        // Pointer auflegen   
        data=nodirectaccess;
    
        // Pointer überprüfen ... funktioniert
        for(i=0;i<4;i++)
        {
        printf("\n*(data+%d) = %d\n",i,*(data+i));
        }
    
        // Die Werte nun in ddarray[2][2] formatieren, das kostet CPU Leistung auf dem
        // Embedded Prozessor. In Wirklichkeit liegt eine RGB Matrix vor. Jeder Kanal
        // wird durch ein 1D Array repräsentiert wie oben nodirectaccess[]. Die
        // for-Schleife müsste demnach 640*480*3 Zugriffe durchführen, nur für die
        // Addressierung. Entspricht 921600 Einzelzugriffen im Flash....
        // 
        for(i=0;i<max_i;i++)
        {
           for(j=0;j<max_j;j++)
           {
                               // Bottleneck
                               ddarray[i][j]=*(data+i+j);
                               printf("\nddarray[%d][%d]= %d",i,j,ddarray[i][j]);
    
           }
        }
    
      system("PAUSE");	
      return 0;
    }
    


  • So geht´s

    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char *argv[])
    {
        // Obligatorisch
        const int max_i=3;
        const int max_j=3;
        register int i,j;
    
        // Ein externes Array auf das nur mit Pointer zugegriffen werden kann (MATLAB)
        int nodirectaccess[]={3,5,7,2,4,7,1,9,3}; 
        // Der Pointer der darauf zugreift
        int *data;
        // Das Zielarray 2*2 Elemente soll aus 1*4 Elemente erstellt werden
        int ddarray[3][3]={0};
    
        // Pointer auflegen   
        data=nodirectaccess;
    
        // Pointer überprüfen ... funktioniert
        for(i=0;i<9;i++)
        {
        printf("\n*(data+%d) = %d",i,*(data+i));
        }
    
        // Die Werte nun in ddarray[2][2] formatieren, das kostet CPU Leistung auf dem
        // Embedded Prozessor. In Wirklichkeit liegt eine RGB Matrix vor. Jeder Kanal
        // wird durch ein 1D Array repräsentiert wie oben nodirectaccess[]. Die
        // for-Schleife müsste demnach 640*480*3 Zugriffe durchführen, nur für die
        // Addressierung. Entspricht 921600 Einzelzugriffen im Flash....
    
        // Alternative
        int (*tmp)[3]=data;
    
        for(i=0;i<max_i;i++)
        {
           for(j=0;j<max_j;j++)
           {
             printf("\n\t\ttmp    [%d][%d] = %d",i,j,tmp[i][j]);
           }
        }
    
      system("PAUSE");	
      return 0;
    }
    


  • #include <stdio.h> 
    #include <stdlib.h> 
    int main() 
    { 
    
        const int max_i=3; 
        const int max_j=3; 
        register int i,j; 
    
        // Ein externes Array auf das nur mit Pointer zugegriffen werden kann (MATLAB) 
        int nodirectaccess[]={3,5,7,2,4,7,1,9,3}; 
    
        for(i=0;i<9;i++) 
        { 
        printf("\n*(data+%d) = %d",i, nodirectaccess[i]); //eindimensionaler Zugriff
        } 
    
        for(i=0;i<max_i;i++) 
        { 
           for(j=0;j<max_j;j++) 
           { 
             printf("\n\t\ttmp    [%d][%d] = %d",i,j, ((int(*)[3])nodirectaccess)[i][j]); 
           } // ((int(*)[3])nodirectaccess) ist der Cast auf den von Dir gewünschten  Zeiger[3][3]                                    
        } 
    
      system("PAUSE");    
      return 0; 
    }
    

    Du hast ein eindimensionales Array namens nodirectaccess[].
    Wenn Du es zweidimensional ansprechen willst, muss dieser Zeiger gecastet werden, siehe oben.
    Es muss nichts formatiert weden!
    Durch den Cast kennt der Compiler die neue Feldgrenze([3]) und erstellt optimalen Code für Zugriff.

    mfg


Log in to reply