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 1
die Ausgabe
0 0 1 0 -> 0 0 0 0
Das 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 2
Bin 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_if
und dem rosa Rattenschwanz (shift_chain
. Inbitonic_sort
wird 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
swap
entweder inshift_swap_if_help
oderreverse_if
um, 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] = {};