Ermitteln von ARGB aus einer Pixmap

Übersicht BlitzMax, BlitzMax NG FAQs und Tutorials

Neue Antwort erstellen

BladeRunner

Moderator

Betreff: Ermitteln von ARGB aus einer Pixmap

BeitragFr, Okt 23, 2009 23:04
Antworten mit Zitat
Benutzer-Profile anzeigen
es gibt ja eine Menge Methoden um aus den 32Bit eines Pixels die Farb- und Alphainformationen auszulesen, aber meist ist man auf Geschwindigkeit angewiesen.
Ich habe daher mal die Methoden welche mir bekannt und geläufig waren auf ihre Performance getestet.

Dies wären im Einzelnen gewesen:
-Shiften per shr und caten in einen Byte
-Shiften per shr und ggf. Maskieren mit $ff
-einen Pointer auf die Info erstellen und den als Array auslesen

Bei jeweils 100 Millionen Durchläufen hat sich dabei die erste Methode bei mir als Sieger herauskristallisiert.

Code: [AUSKLAPPEN]
SuperStrict
Local a:Byte , r:Byte , g:Byte , b:Byte
Local bptr:Byte Ptr
Local argb:Int = $12345678
Local ms:Int = MilliSecs()
For Local i:Int = 0 To 100000000
    a:Byte = Byte(argb Shr 24)
    r:Byte = Byte(argb Shr 16)
    g:Byte = Byte(argb Shr 8)
    b:Byte = Byte(argb)
Next
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

Print (MilliSecs() - ms)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
bptr= Varptr(argb)
    a:Byte = bptr[3]
    r:Byte = bptr[2]
    g:Byte = bptr[1]
    b:Byte = bptr[0]
Next
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)
Print (MilliSecs() - ms)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    a:Byte = argb Shr 24
    r:Byte = (argb Shr 16) &$ff
    g:Byte = (argb Shr 8) &$ff
    b:Byte = (argb) &$ff
Next
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)
Print  (MilliSecs() - ms)


Falls ihr noch schnellere Wege kennt, bitte postet sie, und baut eure Zeitmessung in diesem Beispiel mit ein, damit man einen Vergleich hat.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DaysShadow

BeitragFr, Okt 23, 2009 23:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich kenne zwar keine andere Methode , aber bei mir ist die 2.Methode mit dem Pointer am schnellsten gefolgt von Methode 1 und zuletzt 3.
Bekannt war mir nur die dritte und, bei mir, langsamste Methode =/
Gut zu wissen.

MfG DaysShadow
Blessed is the mind too small for doubt

BladeRunner

Moderator

BeitragFr, Okt 23, 2009 23:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist fürwahr interessant zu wissen. Debug oder Release-Mode? Ändert es was wenn du auf eine Milliarde Durchläufe gehst oder die Reihenfolge im Code umstellst?
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DaysShadow

BeitragFr, Okt 23, 2009 23:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Besagte Reihenfolge ist für Release, im Debug sieht es wieder anders aus, da ist Methode 1 am schnellsten gefolgt von Methode 3 und zuletzt 2.
Eine Milliarde Durchgänge ändert im Release nichts an der Reihenfolge und auch umstellen im Code bewirkt bei mir keine Änderung.
Blessed is the mind too small for doubt

BladeRunner

Moderator

BeitragFr, Okt 23, 2009 23:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist echt seltsam, ich hätte vermutet dass die Ergebnisse gleichbleiben. Du benutzt eine AMD-CPU? ich habe Intel, vielleicht regelt das die CPU anders. Kann das jemand anderes untermauern?
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

FireballFlame

BeitragFr, Okt 23, 2009 23:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Reihenfolge: 1 - 2 - 3, sowohl im Debug als auch im Release
Intel
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Der Eisvogel

BeitragSa, Okt 24, 2009 0:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich hab bisher immer diese verwendet:
Code: [AUSKLAPPEN]
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    a:Byte = (argb & $FF000000) / $1000000
    r:Byte = (argb & $FF0000) / $10000
    g:Byte = (argb & $FF00) / $100
    b:Byte = argb & $ff
Next
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)
Print  (MilliSecs() - ms)

Im Debugmodus war sie an 2. Stelle. Aber Ohne Debug an Letzter.

MfG
Der Eisvogel
Ungarische Notation kann nützlich sein.
BlitzMax ; Blitz3D
Win 7 Pro 64 Bit ; Intel Core i7-860 ; 8 GB Ram ; ATI HD 5750 1 GB
Projekte: Window-Crasher
Ich liebe es mit der WinAPI zu spielen.

Xaymar

ehemals "Cgamer"

BeitragSa, Okt 24, 2009 1:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit debug:
1 - 3 - 2
Ohne/Release:
2 - 1&3(gleichschnell)

AMD Athlon 64 x2 5200+, 32bit Windows
Warbseite

BtbN

BeitragSa, Okt 24, 2009 10:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Debug:

Code: [AUSKLAPPEN]
00000012 00000034 00000056 00000078
3939
00000012 00000034 00000056 00000078
4394
00000012 00000034 00000056 00000078
4024


Release:

Code: [AUSKLAPPEN]
00000012 00000034 00000056 00000078
283
00000012 00000034 00000056 00000078
323
00000012 00000034 00000056 00000078
324


In Beiden fällen ist methode 1 am schnellsten, was aber eigentlich jeder logik wiederspricht, da methode 2 eigentlich unschlagbar sein müsste, da dabei auf einen fixen speicher-bereich zugegriffen wird. Daraus schließe ich mal, BMax macht da irgend nen mist. Bastel gerade an ner weiteren methode, einen moment bitte Wink


Edit: So habe mal ein paar weitere methoden, und einen direkten C-Vergleich eingebaut:

BMax-File:

Code: [AUSKLAPPEN]
SuperStrict

Framework BRL.StandardIO
Import BRL.Retro
Import BRL.Random

Import "test.c"

Extern "C"
   Function DoArgbBytes(argb:Int, a:Byte Ptr, r:Byte Ptr, g:Byte Ptr, b:Byte Ptr)="bb_do_argb_bytes"
   Function DoArgbBytes2(argb:Int, a:Byte Ptr, r:Byte Ptr, g:Byte Ptr, b:Byte Ptr)="bb_do_argb_bytes2"
   Function bb_do_c_test(rndseedd:Int)
EndExtern

Global rndsd:Int = MilliSecs()

Local a:Byte , r:Byte , g:Byte , b:Byte
Local argb:Int = $12345678
Local bptr:Byte Ptr = Varptr argb

SeedRnd(rndsd)
Local ms:Int = MilliSecs()
For Local i:Int = 0 To 100000000
    argb = Rand(0, $FFFFFFF)
    a:Byte = Byte(argb Shr 24)
    r:Byte = Byte(argb Shr 16)
    g:Byte = Byte(argb Shr 8)
    b:Byte = Byte(argb)
Next
Print (MilliSecs() - ms)
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

SeedRnd(rndsd)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    argb = Rand(0, $FFFFFFF)
    a:Byte = bptr[3]
    r:Byte = bptr[2]
    g:Byte = bptr[1]
    b:Byte = bptr[0]
Next
Print (MilliSecs() - ms)
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

SeedRnd(rndsd)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    argb = Rand(0, $FFFFFFF)
    a:Byte = argb Shr 24
    r:Byte = (argb Shr 16) &$ff
    g:Byte = (argb Shr 8) &$ff
    b:Byte = (argb) &$ff
Next
Print  (MilliSecs() - ms)
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

SeedRnd(rndsd)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    argb = Rand(0, $FFFFFFF)
    DoArgbBytes(argb, Varptr a, Varptr r, Varptr g, Varptr b)
Next
Print  (MilliSecs() - ms)
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

SeedRnd(rndsd)
ms = MilliSecs()
For Local i:Int = 0 To 100000000
    argb = Rand(0, $FFFFFFF)
    DoArgbBytes2(argb, Varptr a, Varptr r, Varptr g, Varptr b)
Next
Print  (MilliSecs() - ms)
Print Hex(a) + " " + Hex(r) + " " + Hex(g) + " " + Hex(b)

bb_do_c_test(rndsd)

End


C-File:

Code: [AUSKLAPPEN]
#include <stdlib.h>
#include <stdio.h>

int bbMilliSecs();
int brl_random_Rand(int min, int max);
void brl_random_SeedRnd(int seed);

union uni_argb
{
   int argb;
   struct
   {
      unsigned char b;
      unsigned char g;
      unsigned char r;
      unsigned char a;
   };
};

void bb_do_argb_bytes(int argb, unsigned char * a, unsigned char * r, unsigned char * g, unsigned char * b)
{
   union uni_argb var;
   var.argb = argb;
   (*a) = var.a;
   (*r) = var.r;
   (*g) = var.g;
   (*b) = var.b;
}

void bb_do_argb_bytes2(int argb, unsigned char * a, unsigned char * r, unsigned char * g, unsigned char * b)
{
   (*a) = ((unsigned char*)(&argb))[3];
   (*r) = ((unsigned char*)(&argb))[2];
   (*g) = ((unsigned char*)(&argb))[1];
   (*b) = ((unsigned char*)(&argb))[0];
}

void bb_do_c_test(int rndseedd)
{
   int argb = 0x12345678;
   unsigned char a = 0, r = 0, g = 0, b = 0;
   union uni_argb var;

   brl_random_SeedRnd(rndseedd);
   int ms = bbMilliSecs();

   int i = 0;
   for(i = 0; i <= 100000000; i++)
   {
      argb = brl_random_Rand(0, 0xFFFFFFF);
      var.argb = argb;
      a = var.a;
      r = var.r;
      g = var.g;
      b = var.b;
   }

   ms = bbMilliSecs() - ms;

   printf("%d\n", ms);
   printf("%x %x %x %x\n", a, r, g, b);


   brl_random_SeedRnd(rndseedd);
   ms = bbMilliSecs();

   for(i = 0; i <= 100000000; i++)
   {
      argb = brl_random_Rand(0, 0xFFFFFFF);
      a = ((unsigned char*)(&argb))[3];
      r = ((unsigned char*)(&argb))[2];
      g = ((unsigned char*)(&argb))[1];
      b = ((unsigned char*)(&argb))[0];
   }

   ms = bbMilliSecs() - ms;

   printf("%d\n", ms);
   printf("%x %x %x %x\n", a, r, g, b);
}


Meine Ergebnisse dazu:

Release:
Code: [AUSKLAPPEN]
6290
00000004 000000DA 0000004D 00000072
5196
00000004 000000DA 0000004D 00000072
6485
00000004 000000DA 0000004D 00000072
6560
00000004 000000DA 0000004D 00000072
6540
00000004 000000DA 0000004D 00000072
5033
4 da 4d 72
5028
4 da 4d 72


Debug:
Code: [AUSKLAPPEN]
23116
00000006 00000086 000000C5 000000C5
23469
00000006 00000086 000000C5 000000C5
23245
00000006 00000086 000000C5 000000C5
22112
00000006 00000086 000000C5 000000C5
21042
00000006 00000086 000000C5 000000C5
16317
6 86 c5 c5
17443
6 86 c5 c5



Hab das ganze auf random mit nem fixen wert gestellt, um vergleichbarkeit zwischen C und BMax zu erreichen, da C eine Schleife, wie sie in BMax ist, einfach wegoptimiert, und so der vergleich auf 5000ms BMax und 2ms C endete.

Dante

BeitragSo, Okt 25, 2009 21:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Im Release:
2 - 1 - 3
mit 255ms - 353ms - 395ms

und im Debug:
1 - 3 - 2
mit 6260ms - 6342ms - 6638ms

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG FAQs und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group