Absolute Differenz von Bild berechnen



  • Schade. 😉
    Aber das klingt ja schonmal vielversprechend:

    The ARMv7 architecture introduced the Advanced SIMD extension (NEON) as an optional extension to 
    the ARMv7-A and ARMv7-R profiles. NEON technology is a 64/128-bit hybrid SIMD architecture that 
    allows up to 16 data elements to be processed in parallel, thus accelerating media and signal processing 
    applications.
    

    [url]
    http://www.incubesol.com/images/Optimization of Multimedia Codecs using ARM NEON.pdf
    [/url]



  • flexbex schrieb:

    Schade. 😉
    Aber das klingt ja schonmal vielversprechend:

    The ARMv7 architecture introduced the Advanced SIMD extension (NEON) as an optional extension to 
    the ARMv7-A and ARMv7-R profiles. NEON technology is a 64/128-bit hybrid SIMD architecture that 
    allows up to 16 data elements to be processed in parallel, thus accelerating media and signal processing 
    applications.
    

    [url]
    http://www.incubesol.com/images/Optimization of Multimedia Codecs using ARM NEON.pdf
    [/url]

    prächtig.
    Damit komme ich auf http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html
    Damit haste ja praktisch schon gewonnen: Beim googlen der Intrinsics müssen ja Quellcodes auftauchen, die sowas benutzen.

    Sicherheitshalber würde ich nochmal mit -mfpu=neon -O3 das Makro vom Threadbeginn messen.



  • ich bin jetzt hier gelandet

    CFLAGS=-c -DRELEASE -UDEBUG -mfpu=neon -mcpu=cortex-a8 -march=armv7-a -tune=cortex-a8  -Wall -pg -O3
    LDFLAGS=-pg -O3 -lgsl -lgslcblas
    

    leider habe ich aber gsl nicht mit den Flags compiliert. Könnte sein das dann was nich geht

    Cortex-A8 and Cortex-A9 can do only two SP FP multiplications per cycle, so you may at most double the performance on those (most popular) CPUs. In practice, ARM CPUs have very low IPC, so it is preferably to unroll the loops as much as possible. If you want ultimate performance, write in assembly: gcc's code generator for ARM is nowhere as good as for x86.
    
    I also recommend to use CPU-specific optimization options: "-O3 -mcpu=cortex-a9 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mthumb" for Cortex-A9; for Cortex-A15, Cortex-A8 and Cortex-A5 replace -mcpu=-mtune=cortex-a15/a8/a5 accordingly. gcc does not have optimizations for Qualcomm CPUs, so for Qualcomm Scorpion use Cortex-A8 parameters (and also unroll even more than you usually do), and for Qualcomm Krait try Cortex-A15 parameters (you will need a recent version of gcc which supports it).
    


  • ja Super jetzt bin ich schon bei

    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  us/call  us/call  name    
     77.05    101.76   101.76                             FilterFlow_BrutForc_
    

    ich mach das übrigens über 3000 Bilder und auf jedem bild 2* 140

    damit bin ich jetzt bei 1,7us

    ma gucken ob da mehr geht 🙂


  • Mod

    Aus Interesse: Hast du die verschiedenen Codevarianten mal verglichen?



  • Ach so ja das war das was ich gemacht habe

    einmal zwei verschiedene ABS funktionen. Die zweite ist schneller gewesen

    #define absDiff(a1,a2) (((a1)>(a2))?a1-a2:a2-a1)
    
    std::abs(a[ix+iy]-b[ix+iy])
    

    und zwei verschiedene Berchnungsarten einmal mit Define und einmal mit Schleife

    #define CalculateDifference(a,b) \
     absDiff(a[0*imSizeX+0],b[0*imSizeX+0])+absDiff(a[0*imSizeX+1],b[0*imSizeX+1])+absDiff(a[0*imSizeX+2],b[0*imSizeX+2])+absDiff(a[0*imSizeX+3],b[0*imSizeX+3])\
    +absDiff(a[0*imSizeX+4],b[0*imSizeX+4])+absDiff(a[0*imSizeX+5],b[0*imSizeX+5])+absDiff(a[0*imSizeX+6],b[0*imSizeX+6])+absDiff(a[0*imSizeX+7],b[0*imSizeX+7])\
    +absDiff(a[1*imSizeX+0],b[1*imSizeX+0])+absDiff(a[1*imSizeX+1],b[1*imSizeX+1])+absDiff(a[1*imSizeX+2],b[1*imSizeX+2])+absDiff(a[1*imSizeX+3],b[1*imSizeX+3])\
    +absDiff(a[1*imSizeX+4],b[1*imSizeX+4])+absDiff(a[1*imSizeX+5],b[1*imSizeX+5])+absDiff(a[1*imSizeX+6],b[1*imSizeX+6])+absDiff(a[1*imSizeX+7],b[1*imSizeX+7])\
    +absDiff(a[2*imSizeX+0],b[2*imSizeX+0])+absDiff(a[2*imSizeX+1],b[2*imSizeX+1])+absDiff(a[2*imSizeX+2],b[2*imSizeX+2])+absDiff(a[2*imSizeX+3],b[2*imSizeX+3])\
    +absDiff(a[2*imSizeX+4],b[2*imSizeX+4])+absDiff(a[2*imSizeX+5],b[2*imSizeX+5])+absDiff(a[2*imSizeX+6],b[2*imSizeX+6])+absDiff(a[2*imSizeX+7],b[2*imSizeX+7])\
    +absDiff(a[3*imSizeX+0],b[3*imSizeX+0])+absDiff(a[3*imSizeX+1],b[3*imSizeX+1])+absDiff(a[3*imSizeX+2],b[3*imSizeX+2])+absDiff(a[3*imSizeX+3],b[3*imSizeX+3])\
    +absDiff(a[3*imSizeX+4],b[3*imSizeX+4])+absDiff(a[3*imSizeX+5],b[3*imSizeX+5])+absDiff(a[3*imSizeX+6],b[3*imSizeX+6])+absDiff(a[3*imSizeX+7],b[3*imSizeX+7])\
    +absDiff(a[4*imSizeX+0],b[4*imSizeX+0])+absDiff(a[4*imSizeX+1],b[4*imSizeX+1])+absDiff(a[4*imSizeX+2],b[4*imSizeX+2])+absDiff(a[4*imSizeX+3],b[4*imSizeX+3])\
    +absDiff(a[4*imSizeX+4],b[4*imSizeX+4])+absDiff(a[4*imSizeX+5],b[4*imSizeX+5])+absDiff(a[4*imSizeX+6],b[4*imSizeX+6])+absDiff(a[4*imSizeX+7],b[4*imSizeX+7])\
    +absDiff(a[5*imSizeX+0],b[5*imSizeX+0])+absDiff(a[5*imSizeX+1],b[5*imSizeX+1])+absDiff(a[5*imSizeX+2],b[5*imSizeX+2])+absDiff(a[5*imSizeX+3],b[5*imSizeX+3])\
    +absDiff(a[5*imSizeX+4],b[5*imSizeX+4])+absDiff(a[5*imSizeX+5],b[5*imSizeX+5])+absDiff(a[5*imSizeX+6],b[5*imSizeX+6])+absDiff(a[5*imSizeX+7],b[5*imSizeX+7])\
    +absDiff(a[6*imSizeX+0],b[6*imSizeX+0])+absDiff(a[6*imSizeX+1],b[6*imSizeX+1])+absDiff(a[6*imSizeX+2],b[6*imSizeX+2])+absDiff(a[6*imSizeX+3],b[6*imSizeX+3])\
    +absDiff(a[6*imSizeX+4],b[6*imSizeX+4])+absDiff(a[6*imSizeX+5],b[6*imSizeX+5])+absDiff(a[6*imSizeX+6],b[6*imSizeX+6])+absDiff(a[6*imSizeX+7],b[6*imSizeX+7])\
    +absDiff(a[7*imSizeX+0],b[7*imSizeX+0])+absDiff(a[7*imSizeX+1],b[7*imSizeX+1])+absDiff(a[7*imSizeX+2],b[7*imSizeX+2])+absDiff(a[7*imSizeX+3],b[7*imSizeX+3])\
    +absDiff(a[7*imSizeX+4],b[7*imSizeX+4])+absDiff(a[7*imSizeX+5],b[7*imSizeX+5])+absDiff(a[7*imSizeX+6],b[7*imSizeX+6])+absDiff(a[7*imSizeX+7],b[7*imSizeX+7])\
    
    #define CalculateDifference(a,b)\
    	uint32_t ergebniss=0;\
    	for(int16_t iy=0; iy<8*imSizeX; iy+=imSizeX) { \
    		for(int16_t ix=0; ix<8; ix++) { \
    			ergebniss+=std::abs(a[ix+iy]-b[ix+iy]) ;\
    		}\
    	}\
    

    Ergebnis zwischen std::abs und #define absDiff(a1,a2) (((a1)>(a2))?a1-a2:a2-a1)
    hat std::abs gewonnen

    zwischen schleife und großem define gabs keinen Unterschied.

    Deshalb würd ich wohl die schleife wegen der Lesbarkeit nehmen. Bei der schleife war's besser wenn ich inkrementiere als dekrementiere. kommisch hatte es immer anders rum gelernt.
    war aber auch nur geringfügig der Unterschied



  • Soweit ich gelesen haben, kann man mit Handoptimierung nochmal bis zu der 35 fachen Geschwindigkeit raus holen. Handoptimierung bedeutet, dass du deinen Algo genau auf deinen CPU-Typ abstimmst(verschiedene Caches berücksichtigen etc.). Intel macht dies so in ihren IPP(http://software.intel.com/en-us/intel-ipp). Eine Erklärung, warum da noch viel mehr raus zu holen ist, als mit jeder möglichen Compiler-Einstellung, findest du hier in einem Vortrag zum schnellen Rechnen: http://www.multimedia.ethz.ch/speakers/lecture/?doi=10.3930/ETHZ/AV-d1c72caf-76ef-4834-b0b5-7350edf25710&autostart=true



  • Ich hab nur leider einen arm prozessor. Aber da gibt es auch was für. Steht bisschen weiter oben im Thread.Ich teste das heute ma und kann heute abend ma die ergebniss zeigen


Anmelden zum Antworten