Warum ich kein Demoscenecoder bin
Samstag, 16.1.2016, 10:04 > daMaxWie der eine oder die andere sicher schon mitbekommen hat, verdiene ich meine Brötchen am Computer. Genauer gesagt mit Softwareentwicklung, mal in Java, mal in Objective-C, meistens aber im Windows-Umfeld mit VB.net oder C# (und wenn es unbedingt sein muss, zähneknirschend manchmal auch noch mit VB6 oder *seufz* VBS), mein Blog mit dem ganzen HTML/JS/CSS-Gefrickel nicht zu vergessen. Das beherrsche ich inzwischen leidlich gut, obwohl ich ehrlich gestehen muss, dass mich die ganze Chose mittlerweile doch wieder mehr langweilt als begeistert. Aber ich schweife ab.
Was ich sagen wollte: gestern Nacht hatte ich eine Idee für ein Easteregg und dazu wollte ich mal sehen, wie man einen Plasmaeffekt codet. Sowas hier. Na, und beim Suchen bin ich über diese Diskussion auf Pouët.net gestoßen, die mir mal wieder deutlich vor Augen führt, warum ich es nie zum Demoscenecoder bringen werde. Die Frage selbst verstehe ich noch, aber schon bei Punkt 3_minus in der Antwort von bdk erscheinen bei mir die ersten Fragezeichen über dem Kopf:
Some quick random hints looking at the code:
1) Always try to use look-up tables when it comes to computationally heavy stuff like sin,cos,tan,sqrt and friends (this should give you a good speed-up...)
2) Using integer math / fixed point math still can improve speed a lot expecially when math precision isn't a must
3_minus)
- multiply for (1/x) instead of dividing for x (if x is constant)
- when doing modulus operations where the divisor is a power of two (x % 2^n) (in your code "... % 256" should be) you can replace it with a faster bitwise AND where "(x & (2^n)) - 1", i.e. x % 256 <-equals-> x & (256 - 1).
- when dividing/multiplying for powers of two (integers) you can use bit shifting (i.e.: x * 32 <--> x << 5). Probably compilers already do these last two kinds of optimizations. (bitwise operations)
Found also this site, maybe you'll find it useful: http://student.kuleuven.be/~m0216922/CG/index.html.
und bei der Antwort von duffman steige ich endgültig aus:
IF the surface width is a power of 2 and the total pixel count is a multiple of 16
IF your buffers are in user memory
then try this
change your loops from this
buf = new int[x, y]
for(int x = 0; x < w; x++)
{
for(int y = 0; y < h; y++)
{
buf[x, y] = code here
...
to something like this
int Log2(int val)
{
ASSERT(val > 0)
int res = -1;
while((1 << ++res) <= val);
return(res - 1);
}
mask = w - 1 //w must be a power of 2 remember
bitshift = Log2(w)
pixelcount = w * h
//initialize buffer like this
buf = new int[pixelcount]
for(int j = 0; j < pixelcount; j += 48)
{
for(int i = 0; i < 16; ++i, ++j)
{
// i is never used
//if you need x and y, here is how to compute them
x = j & mask
y = j >> bitshift
buf[j] = palette[(cls[x,y] + paletteShift)%255];
x = (j+16) & mask
y = (j+16) >> bitshift
buf[j+16] = palette[(cls[x,y] + paletteShift)%255];
x = (j+32) & mask
y = (j+32) >> bitshift
buf[j+32] = palette[(cls[x,y] + paletteShift)%255];
x = (j+48) & mask
y = (j+48) >> bitshift
buf[j+48] = palette[(cls[x,y] + paletteShift)%255];
This memory access method gave me a better speed increase than anything else(in C)
The moral here is, dont access big buffers in user memory sequentially
while((1 << ++res) <= val); Nee ey, das wird in diesem Leben nix mehr.
Naja.. ist halt code, der sehr schnell laufen soll/muss^^
Zuerst wollte ich folgendes schreiben:
"Aber wirklich: while((1 << ++res) <= val);? Da hab ich ja schon schlimmeres gesehen^^
<< ist Shifting nach links. Der Wert wird dabei immer verdoppelt. Genau das wird hier genutzt. Es soll der binäre Logarythmus gefunden werden. Also die Anzahl an Links-Shifts, um über dem gegebenen Wert `val` zu sein.
Du bist in der Bildbearbeitung oder im Performance-Bereich nicht so aktiv ,oder?"
Aber nach kurzem testen kann ich deine Verwirrung verstehen. Zumindest laut dem Name ist die Funktion falsch. Für den richtigen Wert darf nicht '<=' getestet werden, sondern einfach '<'... ;D
Für while((1 << ++res) <= val); kommt bei Log2(4) nämlich 3 raus. Oo
EDIT: my bad... hatte übersehen, dass das return von Log2 noch wieder eins abzieht...
Ist also alles OK mit dem ursprünglichen Algorythmus.
MfG
@Body, Some: hahaha, genau das meine ich Das ist mir einfach zu hoch.
Und nee, ich bin weder in der Bildbearbeitung noch im Performancebereich aktiv. Im Gegenteil: ich bin häppi dass es Managed Code und viel zu schnelle CPUs gibt und bete immer, dass ich mich im gerade aktuellen Projekt nicht mit dem Performance und Diagnostic Hub befassen muss.
Sorry, aber wenn ich komplizierten Code schreiben muss, damit es schneller wird, ist entweder die Standardbibliothek oder der Compiler kaputt. Oder ich hab vergessen, mit -O3 zu kompilieren. Bauen wir Häuser mit schmalen, hohen Fenstern, weil das für die Stabilität einfacher wäre? Oder lassen wir bei Autos nur einen Einstieg von hinten zu, weil das Auto dann leichter und billiger zu produzieren wäre?
Wenn man wirklich auf Geschwindigkeit optimieren muss, dann macht man das nur mit nem Benchmark und Vergleich der Assembler-Instruktionen; Performance-Optimierungen ohne Benchmarking sind Esotherik. Dazu gehört z.B. der Bitshift-Operator, der von gängigen Compilern zum gleichen Code compiliert wird, wie die Multiplikation mit Zweierpotenzen.
1) Für sin/cos/tan/log/exp gibt es Prozessorinstruktionen in CISC-CPUs, also auf Intel- und AMD-CPUs. Die sind schon sehr schnell, da noch LookupTables zu verwenden, generiert eher unnötigen Code ⇒ unnötiges Risiko für Programmierfehler. Den Tipp würde ich höchstens auf nem Mikrocontroller beachten, wo es keine solchen Instruktionen gibt. Situation auf Smartphones ist mir nicht bekannt, ARM ist zwar RISC, hat also keine solchen Instruktionen, aber oft Mathe-Coprozessoren.
2) Stimmt. Ganzzahlarithmetik ist wesentlich billiger.
3) Bringt nur was, wenn dein Compiler kaputt ist.
Besonders wenn man für professionelles Umfeld programmiert, gilt, dass Code viel öfter gelesen als geschrieben wird. Lesbarkeit ist also eines der wichtigsten Kriterien beim Programmieren.
Und die Antwort von duffman bringt schon wieder neuen Code, der manuell für irgend etwas optimiert wurde. Sprachen mit JIT (Just-In-Time Compiler) wie Java oder C# haben hier einen großen Vorteil. Ob man in C/C++ hierfür Lesbarkeit opfern sollte, muss man sich gut überlegen.
Der Thread ist aber auch schon über 8 Jahre alt, Compiler sind seitdem wesentlich besser geworden. Der Link zur KU Leuven ist auch schon kaputt deswegen.
@Chris: noch einer, der nie Demoscenecoder wird
Ja, vielleicht ist auch mein Perfektionismus hinderlich. Oder Prinzipienreiterei
@Chris: Das Problem beim Demos Coden ist einfach das die Dateigröße so klein wie möglich bleiben soll. Da kommts am ende wirklich auf jedes einzelne Zeichen Code an.
Was da bei Dateigrößen im KB-Bereich an effekten und Ton rauskommt ist da schon faszinierend.
Hab nen Bekannten, der in der Szene unterwegs ist (und bei nem kleinen Demoscene-Radio mitmacht), der hat mir da paar Beispiele zukommen lassen, da konnt ich auch nur noch mit den Ohren wackeln.