Von wo aus willst du das denn machen? Ich bin im Moment auch inder TU (in einem der Interneträume), und hier geht alles ohne Proxy? Hast du keine volle Konnektivität?
Beiträge von escitalopram
-
-
Falls es jemanden interessiert: Hab mich jetzt ein bisschen in die Dokumentation eingegraben und folgendes implementiert, scheint noch schneller zu sein:
Codeinline unsigned char q32(register unsigned int x) { register unsigned char result; asm("xor %%ecx,%%ecx; xlatb; movb %%al,%%cl; shr $8, %%eax; xlatb; add %%al,%%cl; shr $8, %%eax; xlatb; add %%al,%%cl; shr $8, %%eax; xlatb; add %%al,%%cl; ":"=c" (result):[tabelle] "b" (quersumme_8), [wert] "a" (x)); return result; }
-
Hmm... na gut, zum ersten kann ich PPC-Assembler noch weniger lesen und zum zweiten hat der einen ganz anderen Registersatz... Aber ich glaub es reicht mir 4 Milliarden Bit-Quersummen in ~30 Sekunden berechnen zu können (ist das gut bei 1,6 GHz?)... Im Notfall kann ich mein Programm ja noch später optimieren...
-
Seltsam, das liefert bei mir längeren Code, mit zusätzlichen ANDs, wieder einem unnötigen shr (das müsste man ja mit den h- und l-registern machen können) und auf dem Stack pfuscht er erst wieder herum (das scheint wohl ohne inline-assembler nicht zu vermeiden zu sein):
Code
Alles anzeigenDump of assembler code for function _ZN9P211quersumme32Ej: 0x08048a90 <P2::quersumme32(unsigned int)+0>: push %ebp 0x08048a91 <P2::quersumme32(unsigned int)+1>: mov %esp,%ebp 0x08048a93 <P2::quersumme32(unsigned int)+3>: mov 0x8(%ebp),%ecx 0x08048a96 <P2::quersumme32(unsigned int)+6>: mov %ecx,%eax 0x08048a98 <P2::quersumme32(unsigned int)+8>: mov %ecx,%edx 0x08048a9a <P2::quersumme32(unsigned int)+10>: shr $0x10,%eax 0x08048a9d <P2::quersumme32(unsigned int)+13>: shr $0x18,%edx 0x08048aa0 <P2::quersumme32(unsigned int)+16>: and $0xff,%eax 0x08048aa5 <P2::quersumme32(unsigned int)+21>: movzbl 0x8049540(%eax),%eax 0x08048aac <P2::quersumme32(unsigned int)+28>: add 0x8049540(%edx),%al 0x08048ab2 <P2::quersumme32(unsigned int)+34>: movzbl %ch,%edx 0x08048ab5 <P2::quersumme32(unsigned int)+37>: and $0xff,%ecx 0x08048abb <P2::quersumme32(unsigned int)+43>: add 0x8049540(%edx),%al 0x08048ac1 <P2::quersumme32(unsigned int)+49>: add 0x8049540(%ecx),%al 0x08048ac7 <P2::quersumme32(unsigned int)+55>: leave 0x08048ac8 <P2::quersumme32(unsigned int)+56>: movzbl %al,%eax 0x08048acb <P2::quersumme32(unsigned int)+59>: ret End of assembler dump.
Was für eine GCC-Version verwendest du, und wie sieht dein Assembler-Code aus?
Edit: Langsamer ist der Code auch
Edit2: mit -fomit-frame-pointer lässt er den Stack in Ruhe und der Code schrumpft auf 50 Byte und wird auch entsprechend schneller *freu*
-
Hi Leute,
Ich möchte die Binäre Quersumme einer 32 Bit-Zahl möglichst effizient berechnen.
Ich arbeite auf einem Athlon XP Model 8 Prozessor mit angeblich 128kB split L1 Cache.Ich habe mich vorläufig für die folgende Variante entschieden:
Ich denke mal im L1-Cache ist Platz für eine Lookup-Tabelle der Quersummen aller 8-Bit-Zahlen, und da könnte man ja 4 mal pro 32-Bit zahl nachschauen und das Ergebnis zusammenaddieren.
Leider bin ich nicht ganz so sattelfest in Assembler wie ich mir das wünsche, deshalb hab ich angefangen die Funktion in C zu programmieren und dann durch hinschauen auf den generierten Assembler-Code zu optimieren.Code
Alles anzeigenconst char quersumme_8[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3 ,3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3 ,3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; unsigned char quersumme32(register unsigned int x) { register unsigned char a, b; register unsigned char r1,r2; a=quersumme_8[x&0xff]; b=quersumme_8[(x>>8)&0xff]; r1=a+b; x=x>>16; a=quersumme_8[x&0xff]; b=quersumme_8[(x>>8)&0xff]; r2=a+b; return r1+r2; }
Mein GCC macht mit -march=athlon-xp -O3 dann folgendes draus:
Code
Alles anzeigenDump of assembler code for function _ZN9P211quersumme32Ej: 0x08048a90 <P2::quersumme32(unsigned int)+0>: push %ebp 0x08048a91 <P2::quersumme32(unsigned int)+1>: mov %esp,%ebp 0x08048a93 <P2::quersumme32(unsigned int)+3>: mov 0x8(%ebp),%edx 0x08048a96 <P2::quersumme32(unsigned int)+6>: movzbl %dh,%eax 0x08048a99 <P2::quersumme32(unsigned int)+9>: movzbl %dl,%ecx 0x08048a9c <P2::quersumme32(unsigned int)+12>: shr $0x10,%edx 0x08048a9f <P2::quersumme32(unsigned int)+15>: movzbl 0x8049540(%eax),%eax 0x08048aa6 <P2::quersumme32(unsigned int)+22>: add 0x8049540(%ecx),%al 0x08048aac <P2::quersumme32(unsigned int)+28>: movzbl %dl,%ecx 0x08048aaf <P2::quersumme32(unsigned int)+31>: shr $0x8,%edx 0x08048ab2 <P2::quersumme32(unsigned int)+34>: movzbl 0x8049540(%edx),%edx 0x08048ab9 <P2::quersumme32(unsigned int)+41>: add 0x8049540(%ecx),%dl 0x08048abf <P2::quersumme32(unsigned int)+47>: leave 0x08048ac0 <P2::quersumme32(unsigned int)+48>: add %edx,%eax 0x08048ac2 <P2::quersumme32(unsigned int)+50>: movzbl %al,%eax 0x08048ac5 <P2::quersumme32(unsigned int)+53>: ret End of assembler dump.
Jetzt frage ich mich: ist dieser Code wirklich optimal? Wenn ich da hinsehe, sehe ich 2 shr, wo eigentlich nur eins benötigt würde? Und überhaupt, was fummelt der da am Stack herum?
Kann mir vielleicht jemand von den technischen Informatikern (oder sonstigen Assembler-Programmieren) helfen das effizienter in C-inline-assembler hinzukriegen (das sollte mit dem GCC ja gehen..)?
Vielen Dank! -
Ok... es wird noch seltsamer.
Hab jetzt die erste Platte auf den zweiten Controller gehängt, und jetzt gehen alle Platten einwandfrei. Sogar die Wartezeit von Platte #2 ist verschwunden...
-
Hi,
Irgendwie scheint bei meinem Rechner was kaputt zu sein:
Ich habe auf dem ersten IDE-Kanal zwei Platten hängen. Auf der ersten ist eine kleine Windows-Partition, und auf der zweiten ist Linux installiert.Mit der zweiten Festplatte hab ich schon seit Ewigkeiten das Problem, dass sie beim Starten ungefähr 90 Sekunden hängt, und dann kommt erst der Bootloader. Allerdings gabs sonst nie ein gröberes Problem mit dieser Platte.
Neuerdings macht jetzt aber die erste Platte große Probleme. Das Windows startet nur mehr im abgesicherten Modus, und das Linux kann die Partitionstabelle der ersten nicht mehr lesen.
Ich hab mir das ganze genauer angesehen und die Partitionstabelle mit dd eingelesen und mit hexdump ausgegeben, und bin draufgekommen, dass die Festplatte zwar alles liest, aber anscheinend bei jeder Leseoperation ungefähr 14 Nullbytes voranstellt. Witzigerweise tritt dieses Problem aber nur im DMA-Modus auf. Wenn ich im PIO-Modus einlese, sind alle Daten korrekt. Die zweite Platte arbeitet im DMA-Modus einwandfrei.
Offensichtlich hat es da irgendwas gröberes, und ich muss was neu kaufen - entweder eine neue Festplatte oder einen neuen Controller == neues Mainboard. Nur hab ich endlich viel Geld, da Student und kann/will nix unnötiges kaufen.
Hat jemand schon mal sowas gehabt? irgendeine Idee, was da hin sein könnte?
-
Hi,
Ich versuche ein Programm zu schreiben, das mir eine bestimmte Stelle in einem bestimmten X-Fenster automatisch anklickt. Allerdings scheine ich da irgendwas falsch zu machen, denn das Programm läuft zwar klaglos durch, aber der Klick wird nicht ausgeführt. (Ja ich rechne auch die Hex-Fensternummer vom xwininfo in dezimal um)C
Alles anzeigen#include <stdlib.h> #include <iostream> #include <X11/Xlib.h> using namespace std; int main (int argc, char* argv[]) { Display* d; d=XOpenDisplay(0); if (argc!=2) { cout << "Please specify a window number" << endl; exit (-1); } int wn=atoi(argv[1]); cout << "Window number is "<< wn << endl; if (d) { cout << "Display opened sucessfully" << endl; } else { cout << "Cannot open $DISPLAY" << endl; exit(-1); } XButtonEvent e; e.type=ButtonPress; e.button=1; e.state=1; e.window=wn; e.serial=0; e.send_event=true; e.same_screen=true; e.root=XDefaultRootWindow(d); e.subwindow=0; //?! e.time=0; e.x_root=720; // Koordinaten vom Bildschirm nehm ich an, mit xev ausgemessen e.y_root=845; e.x=269; // Koordinaten vom Zielfenster? auch mit xev gemessen e.y=466; // stimmt nicht 100% genau mit [xy]_root zusammen, aber ich denk mal das ist egal cout << "XSendEvent says "<< XSendEvent(d, wn, true /* ? */, 0, (XEvent*)&e) << endl; usleep(100000); e.type=ButtonRelease; XSendEvent(d, wn, true /* ? */, 0, (XEvent*)&e); XCloseDisplay(d); return 0; }
Vielleicht gibt's ja hier jemanden im Forum, der mit sowas schon Erfahrung hat und mir da ein bisschen weiterhelfen könnte. Vielen Dank!
-
Gottes willen, ich hab da grad was rausgefunden
Wenn ich die g++ Compilerflags "-ansi" und "-pedantic" verwende, dann kompiliert das Zeug.... SEHR seltsam ist das...
-
Das ändert auch nichts... Findet den Konstruktor auch nicht.
Und davon abgesehen, gibt new nicht ein ShaderManager* zurück? -
Naja, das wär die Headerdatei:
Code
Alles anzeigennamespace Tuft { class ShaderManager { public: ShaderManager(boost::shared_ptr<FileManager> source_); ~ShaderManager(); [...] }; }
und die Klasse verwende ich folgendermaßen:
Codeusing namespace Tuft; int main(int argc, char* argv[]) { boost::shared_ptr<FileManager> fm(new FileManager()); ShaderManager sm(fm); [...]
Die Fehlermeldung sieht dann so aus:
CodeBspTest.cc: In function `int main(int, char**)': BspTest.cc:8: Fehler: keine passende Funktion für Aufruf von »Tuft::ShaderManager::ShaderManager(boost::shared_ptr<Tuft::FileManager>&)« TuftBsp.h:22: Anmerkung: Kandidaten sind: Tuft::ShaderManager::ShaderManager() TuftBsp.h:22: Anmerkung: Tuft::ShaderManager::ShaderManager(const Tuft::ShaderManager&)
achja, und natürlich
-
Hi.
Ich arbeite gerade an einem etwas größeren C++-Projekt und bei mir treten seltsame Phänomene auf; zunächst mal war da ein Problem, dass der compiler (g++) eine deklarierte Klasse nicht gefunden hat, obwohl der Header eingebunden war. Die Lösung für dieses Problem habe ich schon gefunden, und zwar war in ein paar Headern nach dem namespace Y {...} ein Strichpunkt, der wegmusste.Jetzt hab ich ein ähnliches Problem:
Ich hab eine Klasse ShaderManager mit einem Konstruktor ShaderManager(Karl x). Wenn ich diesen Konstruktor nun aber verwenden will, meldet mir g++ es gäbe keinen derartigen Konstruktor, sondern nur den Default- und den Kopierkonstruktor. (Wenn ich das richtig verstanden habe, sollten beide nicht mehr vorhanden sein, wenn ich einen anderen Konstruktor definiert hab....?) Wie kann es sein, dass eine Klassendefinition vom Compiler akzeptiert wird, dieser aber den Konstruktor trotzdem ignoriert? -
Es geht darum, dass eine Klasse keine const members (die man im Konstruktor initialisieren muss) haben kann die arrays sind*, weil man die nicht initialisieren darf. Und mich würde interessieren, warum das so festgelegt wurde, weil irgendwie behindert einen das bei der Arbeit
*) außer es handelt sich um static members
-
Zitat von sauzachn
Es geht für einen ctor nicht - also auch nicht für mehrere.
Abgesehen davon ist das Array wohl nicht mehr konstant, wenn es in verschiedenen ctors verschiedene Werte besitzen soll.Ein Objekt wird nur einmal konstruiert, demnach können (nichtstatische) const members verschiedener Instanzen verschiedene Werte haben, unabhängig davon wieviele Konstruktoren die entsprechende Klasse hat - es sei denn es handelt sich um arrays.......
-
Ok, thx, damit kann ich was anfangen.
Weißt du zufälligerweise auch noch wie man das macht, wenn man mehrere Konstruktoren hat, die das Array mit verschiedenen Werten initialisieren sollen? Eine seltsame Regel ist das...
-
Hi, ich habe ein Problem. Wenn man ein nichtstatisches const-member initialisiert kann man ja nicht folgendes schreiben:
sondern man muss das stattdessen so formulieren:
Soweit so gut, was ist jetzt aber wenn "zahl" ein array ist?
An dieser Stelle bricht mein g++ ab mit der Fehlermeldung
Zitaterror: expected primary-expression before '{' token
Wie mach ich das jetzt richtig? Außerhalb einer Klasse würd ich ja einfach schreiben:
aber in einer Klasse darf ich das ja nicht. Kann mir da bitte jemand weiterhelfen?