Absolute Differenz von Bild berechnen



  • ja schon klar aber ich dachte wenn ich die Schleife rauslasse gehts schneller weil das Program dann nich zur laufzeit rechnen muss

    uint32_t diff=0;
    for(uint16_t iy=0; iy<8*imsSizeX; iy+=imSizeX){
           for(uint16_t ix=0; ix<8; ix++){
                diff+=std::abs(image1[ix+iy]-image2[ix+iy]);
    }
    }
    

    also ihr meint sowas geht schneller?



  • Ich bin mal so frei und behaupte, dass es mit einer Schleife u.U. sogar schneller ist, weil der Compiler das als SIMD-Pattern erkennen kann.



  • Ich gebe gleich mal das Ergebnis ich lass ihn gerade Testen mit gprof



  • also meine Veriante mit
    #define abs(a-b)
    #define das große...

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

    -> das sind auf eine Kachelberechnugn runter gebrochen 1.9us pro 8*8 Kachel



  • mit #define absDiff(a1,a2) (((a1)>(a2))?a1-a2:a2-a1)

    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  us/call  us/call  name    
     84.74    167.09   167.09
    

    -> 3 us

    Mist!



  • Vergleich mal mit einer Inline-Funktion und Schleife...



  • bin ich gerade dabei.
    Ist ein Embedded Arm der hat zwar 1Ghz dauert aber trotzdem 😉



  • mit der for-schleife ist es das Selbe wie beim Ersten.Hab die auch mal als #define gemacht nicht schön aber ging am schnellsten zu Implmentieren. ich hoffe das hat die selbe Wirkung wie Inline

    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  us/call  us/call  name    
     79.11    112.53   112.53                             FilterFlow_BrutForc
    
    #define CalculateDifference(a,b)\
    	uint32_t ergebniss=0;\
    	for(uint16_t iy=0; iy<8*imSizeX; iy+=imSizeX) { \
    		for(uint16_t ix=0; ix<8; ix++) { \
    			ergebniss+=std::abs(a[ix+iy]-b[ix+iy]);\
    		}\
    	}\
    

  • Mod

    Um sicher zu sein: Du benutzt ein optimiertes Compilat?



  • ja
    das habe ich mir als Makefile geschrieben. Ist das in Ordnung?

    CC=g++
    CFLAGS=-c -DRELEASE -UDEBUG  -Wall -g -pg -O3
    LDFLAGS=-g -pg  -lgsl -lgslcblas
    SOURCES=main.cpp debugOwn.cpp FeatGSLMest.cpp FilterFeature_Diff_follow.cpp \
     FilterFlow_BrutForc_follow2.cpp  FlowConstDef.cpp \
    global.cpp LogModul.cpp  mathFunctions.cpp netTcp.cpp \
    VideoDevice_Load.cpp VideoDevice_Caspa.cpp BaseClasses/FeatureCalcGSLBase.cpp \
    BaseClasses/FeatureCalcBase.cpp
    
    OBJECTS=$(SOURCES:.cpp=.o)
    EXECUTABLE=hello
    
    all: $(SOURCES) $(EXECUTABLE)
    
    $(EXECUTABLE): $(OBJECTS)
    	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
    
    .cpp.o:
    	$(CC) $(CFLAGS) $< -o $@
    
    clean:
    	rm -rf *o hello
    
    totalclean:
    
    	rm -rf *o BaseClasses/*o hello
    


  • flexbex schrieb:

    Kann ich das irgendwo nachschauen.

    Guck dir die Disassembly an. Dann weisst du was für Code entsteht.

    Falls kein SIMD Code draus wird, und dein Compiler SIMD-Intrinsics hat, dann kannst du mit denen vermutlich nochmal ordentlich was rausholen.



  • Kannst du mir dabei helfen. Weisst du wie ich mir die von der Commandline ausgeben lassen kann. Aber das finde ich zur not noch raus.

    Aber wie geht das mit SIMD ich habs beim googlen nur überflogen. Also für Arm Prozessoren sollte das ja grundsätzlich funktionieren. Vielleicht kannst du mir auch ne gute stelle zum nachschauen gebn.
    thx



  • Wozu das -g Compilerflag?


  • Mod

    Mit march=dein_prozessortyp kann (nicht muss) eventuell noch mehr rausgeholt werden. Kann sich auch negativ auswirken.
    http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html

    Nexus schrieb:

    Wozu das -g Compilerflag?

    Ist doch ganz nuetzlich fuer den Profiler. Debugsymbole != Debugcode



  • 😉 genau das hab ich auch gerade gelesen. Ich nehm die mal raus
    Die war noch vom debuggen drin



  • flexbex schrieb:

    Kannst du mir dabei helfen. Weisst du wie ...

    Nö, sorry.
    Ich bin ein Windows-Mann. Bei MSVC kann ich dir das alles ausm Stegreif erklären. GCC, GDB etc. = kein Plan. Da hab' ich inetwa nen Überblick was der so kann, aber wie man es genau anstellt müsste ich mir selbst ergoogeln.
    Ebenso was ARM angeht.

    Als Tip kann ich dir nur geben: möglicherweise findest du SIMD Code für verschiedene Compiler/Architekturen für sehr ähnliche oder sogar identische Sachen in der OpenCV. Oder sonstigen Bildberabeitungs-Libraries. Und wenn du ganz viel Glück hast ist die Kombination GCC/ARM dabei 😉



  • 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 🙂


Anmelden zum Antworten