Templates, Bitonic sort und VS 2013 Bug?
-
Nun, ich habe mich auch hingesetzt und ein generisches Sortiernetzwerk mittels Templates erstellt: http://ideone.com/gOIzqH . Funktioniert auch alles .. fast. Der Testfall
test_bitonic<4>(2)liefert unter VS 2013 anstatt des erwarteten Ergebnisses:0 0 1 0 -> 0 0 0 1die Ausgabe
0 0 1 0 -> 0 0 0 0Das passiert nur im Releasemodus. Im Debugmodus ist alles wie erwartet.
Schaue ich mir die angefassten Indizes
test_bitonic_index<4>()so kann ich nichts ungewoehnliches feststellen1 0 3 2 3 0 2 1 1 0 3 2Bin grad etwas ratlos und finde den Fehler nicht. Sieht ihn jemand von euch? Komischerweise verschwindet der Fehler, wenn ich mittels std::cerr irgendwelche Debugausgaben einsetze. Wahrscheinlich benutze ich std::swap falsch ...

Zur Erklaerung des Sorters: Ich habe von
http://en.wikipedia.org/wiki/Bitonic_sorter das zweite Beispiel implementiert. Dabei besteht ein Block immer aus den braunen Swaps, dass einem Umkehren des "Strings" entspricht (reverse_ifund dem rosa Rattenschwanz (shift_chain. Inbitonic_sortwird der Block maximaler Groesse erzeugt und ihm die jeweils kleineren vorangestellt. Zeigeroffsets haetten auch noch Templateargumente sein koennen, kommt spaeter vielleicht.Edit: Drehe ich die Argumente von
swapentweder inshift_swap_if_helpoderreverse_ifum, so funktioniert alles tadellos korrekt. Wohlegemerkt, XOR ... vertausche ich in beiden Teilen die Argumente, so stellt sich ein aehnlicher Fehler ein. Der beschriebene Fehler tritt nur bei einem Arrayunsigned char a[4]unter 32 Bit auf. Bei andere Datentypen oder anderen Plattformen (x64) tritt der Fehler nicht auf. Der Fehler konnte mit VS 2012 reproduziert werden, nicht aber mit VS 2010.Ich glaube es ist ein Optimierungsbug.
-
Wie ist es denn im release-Modus mit deaktivierter Optimierung?
-
Wahrscheinlich benutze ich std::swap falsch
Wie kommst du darauf? Nein, das ist schon richtig so.
Offensichtlich ein Bug von VC++ (oder irgendwo ist UB/IB). Unter Clang und dem neuesten GCC getestet, kein Fehler erkennbar.
Edit: Drehe ich die Argumente von swap entweder in shift_swap_if_help oder reverse_if um, so funktioniert alles tadellos korrekt.
Das ist sehr merkwürdig. Deutet alles auf irgendeine verbotene Optimierung hin.
Kleiner Tipp: Statt
unsigned char a[Len]; for (auto& e : a) e = 0;Schreibe
unsigned char a[Len] = {};