pruefen, ob alle werte 'wert' haben
-
Aziz schrieb:
Funktioniert aber nur wenn 'array' vom typ bool[] ist oder wenn es vom typ int[] (oder ein ganzzahliger typ eben) ist wobei es garantiert nur Werte wie Nullen bzw. Einsen enthält.
beihilfe zu diesem code schafft
alleTrue &= bool(array[i]);
oder
alleTrue &&= array[i];
-
bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < arrayend; );
-
C/C++ Code:
bool allTrue;
for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < arrayend; );Das wird ja wohl nicht funktionieren....in allTrue steht dannn einfach nur ob das letzte Element true ist. Außerdem find ich's nicht wirklich leserlich, das alles in den Bedingunsteil der for-schleife zu packen. Und Perfomance-Vorteile bringt das auch nicht, oder?
Belehrt mich
Mfg, smasher1985
-
smasher1985 schrieb:
Und Perfomance-Vorteile bringt das auch nicht, oder?
ich schätze sogar, daß es nachteilig ist, die variable allTrue zu benutzen. entweder sie nimmt ein register weg, was der umliegende code gut gebrauchen könnte oder sie benutzt lahmes ram und hält den prozessor auf und macht speicher dirty. natürlich muss die areAllTrue inline sein, um schneller zu sein, als wenn man alles in eine funktion stopft.
-
smasher1985 schrieb:
Belehrt mich
Es funktioniert, weil wenn das letzte Element false ist, ist allTrue false - wenn es true war, dann true. Wenn es aber nicht true, also false war, wird die schleife beendet.
Allerdings ist dieser code trotzdem mies.
eine alternative zu volkards lösung wäre:
/** * \brief all_if checks if all elements in the range are evaluated to true using the predicate * \param begin range begin * \param end corresponding end iterator to begin * \param pred unary predicate * \return true if pred always returned true */ template<typename Iter, class Pred> bool all_if(Iter begin, Iter end, Pred pred) { #ifdef ASL_CONCEPT_CHECK boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost::UnaryFunctionConcept<Pred> >(); #endif while(begin!=end) { if(!pred(*begin)) return false; ++begin; } return true; } //und dann: struct isTrue { template<typename T> bool operator()(T const& val) { return bool(val); } }; if(all_if(arr, arr+size, isTrue<int>())) do_something();
auch wenn volkard diese Lösung wahrscheinlich nicht gefallen wird, weil zu STL lastig
-
freak
-
volkard schrieb:
smasher1985 schrieb:
Und Perfomance-Vorteile bringt das auch nicht, oder?
ich schätze sogar, daß es nachteilig ist, die variable allTrue zu benutzen. entweder sie nimmt ein register weg, was der umliegende code gut gebrauchen könnte oder sie benutzt lahmes ram und hält den prozessor auf und macht speicher dirty. natürlich muss die areAllTrue inline sein, um schneller zu sein, als wenn man alles in eine funktion stopft.
ob es performance vorteile bringt, dürfte stark vom compiler abhängen. jedenfalls dürftest du dich in beiden fällen irren. der umliegende code braucht selbst höchtens zwei oder drei register, also bleibt leicht noch etwas frei, und falls es doch eine speicher variable ist... nun das ist irrelevant - eine vorzögerung ensteht nicht, solange nur geschrieben wird. erst wenn diese variable gelesen und ausgewertet wird, muss der prozessor gegebenenfalls etwas warten... allerdings verfügen die prozessoren heute in aller regel über store-load-forwarding, so dass sich dieser nachteil auch stark relativiert.
es war auch nicht unbedingt nach einer funktion gefragt, wenn es keine sein soll, wirst du nicht um eine hilfsvariable drumherum kommen (wenn die arraygrösse nicht schon zur compilezeit bekannt ist...) - selbst dann ist dieser code nicht unbedingt langsamer.
Allerdings ist dieser code trotzdem mies.
deiner braucht 20 zeilen, um dieses problem zu erschlagen... was selbstverständlich besser ist :p
-
allerdings, wenn die hilfsvariable nicht gefällt - dann eben so:
for( int i = 0; bool( array[ i ] ) && ++i < endarray; ); if ( i >= endarray ) tuedas();
wie mies ist das jetzt?
-
camper schrieb:
Allerdings ist dieser code trotzdem mies.
deiner braucht 20 zeilen, um dieses problem zu erschlagen... was selbstverständlich besser ist :p
Mein Code braucht exakt 1 Zeile. Wie kommst du auf 20?
Oder würdest du sagen, dass
sqrt(7);
20 Zeilen braucht - oder sogar mehr? (ka, wie viel code man für ein sqrt brauchen kann).Dein Code ist einfach nicht lesbar. Du hast eine Schleife die mir absolut nichts sagt -> da muss man erst überlegen was es macht.
ein
if(allTrue())
oder
if(all_if(isTrue()))
ist dagen super lesbar - und mindestens genauso schnell. allerdings habe ich da noch wiederverwendbarkeit dabei. also welchen grund gibt es, hier so eine Schleife zu schreiben?zumal ich Schleifen sowieso nicht mag, die keinen Körper haben - riecht irgendwie nach Fehler
-
@Shade: dein Code kompiliert bei mir nicht
d:\eigene dateien\programmierung\c++\benchmark\main.cpp(64) : error C2275: "isTrue" : Ungültige Verwendung dieses Typs als Ausdruck
d:\eigene dateien\programmierung\c++\benchmark\main.cpp(29) : Siehe Deklaration von 'isTrue'
d:\eigene dateien\programmierung\c++\benchmark\main.cpp(64) : error C2059: Syntaxfehler : ')'
d:\eigene dateien\programmierung\c++\benchmark\main.cpp(64) : error C2143: Syntaxfehler : Fehlendes ';' vor '{'woran liegt das?
Mfg, smasher1985
-
camper schrieb:
jedenfalls dürftest du dich in beiden fällen irren.
cool. das höre ich sonst nur bei java-diskussionen.
der umliegende code braucht selbst höchtens zwei oder drei register,
ich kenne den umliegenden code nicht. und du auch nicht. steckt der uns gezeigte ausschnitt nicht in wirklichkeit in ner schleife? wir wissen es nicht.
also bleibt leicht noch etwas frei, und falls es doch eine speicher variable ist... nun das ist irrelevant - eine vorzögerung ensteht nicht, solange nur geschrieben wird.
also für mich sieht schreiben in eine variable so aus: var=wert; und lesen so: tuwas(var);
aber var&=wert sieht für mich verdammt stark nach lesen und schreiben aus. geht dir das ähnlich?es war auch nicht unbedingt nach einer funktion gefragt, wenn es keine sein soll, wirst du nicht um eine hilfsvariable drumherum kommen
klar geht das. man kommt nur nicht elegant umhin. der klassiker ist wohl, bei fund mit goto tuwas() zu überhüpfen.
-
Das mit der Performance in diesem Fall hat mich jetzt doch mal interessiert. Ich zeig euch einfach mal, wie ich gemessen hab, sagt mir falls da methodisch was faul ist - ich hab sowas noch nicht so oft gemacht...
Die Ergebnisse jedenfalls sind
Camper's Methode mit zusätzlicher Variable: 18.57s
Camper's Methode ohne zusätzliche Variable: 2.46s
Volkard's Methode: 2.90sKommt mir ja ein bisschen zu krass vor, vor allem der Unterschied zwischen den zwei ersten Methoden. Ich kann aber keinen Fehler sehen also klärt mich auf *g*
@Volkard: deine Methode ist nicht 1 zu 1 übernommen. Aber mit double als Typ des ersten Parameters kann das ja nicht kompilieren oder täusch ich mich??
Achja, und noch eine Frage by the way: gibts eine standard-konforme version von QueryPerfomanceCounter bzw. einen entpsrechenden Header?
#include <iostream> #include <windows.h> #include <mmsystem.h> using namespace std; #define NUM 10000000 // hier hab ich den ersten Parameter angepasst... inline bool areAllTrue(bool* array,int arrayend){ for(int i=0;i<arrayend;++i) if(!array[i])//wenn einer mit false gefunden wird return false;//dann sind nicht alle true return true;//wenn keine false in der schleife gefunden wurde, sind's true } void foo() { int j; j=1; } int main() { LONGLONG frequency, currentTime, lastTime; double timeElapsed, timeScale; QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); timeScale = 1.0 / frequency; bool array[100]; for (int j=0; j<100; ++j) array[j] = true; /// CAMPERS METHODE 1 QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// CAMPERS METHODE 2 QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { for (int i = 0; bool( array[ i ] ) && ++i < 100; ); if (i >= 100) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// VOLKARDS METHODE (leicht verändert) QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { if(areAllTrue(array,100)) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; }
Nehmt mal bitte Stellung
Mfg, smasher1985
Edit: Achja, das ganze ist mit MSVC6.0 kompiliert
-
es gibt keinen guten grund diese diskussion weiterzuführen. der code, so wie er ist, funktioniert und verletzt keine standards. und die tatsache, dass keiner von uns weiss, was der umliegende code tut, kann wohl kaum als argument dagegen verwendet werden. &&= bzw. &= kommt in meinem code gar nicht vor; und bzgl. der hilfsvariable habe ich micht auch bereits selbst widerlegt - kein grund das noch einmal anzuführen.
die stl variante ist sicherlich eine gute möglichkeit, die man in den meisten fällen vorziehen wird. aber auf irgendeine magische weise schneller oder weniger resourcenintensiv ist sicherlich nicht.
mein code ist und war nur als optimierung der vorangegangenen beispiele gedacht - und er ist schneller und prägnanter als diese. ich begreife nicht, wieso das soviel widerspruch hervorruft.
-
mit vc++7.1 bekomme ich diese werte:
1.94414
1.82313
1.84317möglich das vc6 erst den zugewiesenen ausdruck auf true prüft - in dem falle wäre es nat. eine schreib-lese-vorgang, der zeit kostet - auf jeden fall eine schwäche des compilers.
-
ich habe diesen 'benchmark' noch einmal untersucht und kleine änderungen vorgenommen:
#include <iostream> #include <windows.h> #include <mmsystem.h> using namespace std; #define NUM 100000000 // hier hab ich den ersten Parameter angepasst... inline bool areAllTrue(bool* array,int arrayend){ for(int i=0;i<arrayend;++i) if(!array[i])//wenn einer mit false gefunden wird return false;//dann sind nicht alle true return true;//wenn keine false in der schleife gefunden wurde, sind's true } void foo() { int j; j=1; } /* __declspec( naked ) bool __fastcall areAllTrue(bool* array,int arrayend) { __asm { psubb mm0, mm0 push edx movq mm1, mm0 xor eax, eax and edx, 0xfffffff0 movq mm2, mm0 jz _xx lea ecx, [ ecx + edx ] neg edx _loop: pcmpeqb mm0, [ ecx + edx ] por mm2, mm0 pcmpeqb mm1, [ ecx + edx + 8 ] add edx, 16 por mm2, mm1 jnz _loop psubb mm0, mm0 pcmpeqb mm0, mm2 pmovmskb eax, mm0 test eax, eax jnz _false _xx: emms pop edx and edx, 0xf jz _true add ecx, edx neg edx _loop2: cmp byte ptr [ ecx + edx ], 1 inc edx jc _false2 jnz _loop2 _true: inc eax ret _false: pop edx _false2:emms xor eax, eax ret } } */ int main() { LONGLONG frequency, currentTime, lastTime; double timeElapsed, timeScale; QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); timeScale = 1.0 / frequency; bool array[100]; for (int j=0; j<100; ++j) array[j] = true; /// CAMPERS METHODE 1 QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// CAMPERS METHODE 2 QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { for (int i = 0; bool( array[ i ] ) && ++i < 100; ); if (i >= 100) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// VOLKARDS METHODE (leicht verändert) QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { if(areAllTrue(array,100)) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// CAMPERS METHODE 2 QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { for (int i = 0; bool( array[ i ] ) && ++i < 100; ); if (i >= 100) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; /// VOLKARDS METHODE (leicht verändert) QueryPerformanceCounter((LARGE_INTEGER*)&lastTime); { for (int j=0; j < NUM; ++j) { if(areAllTrue(array,100)) { foo(); } } } QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); timeElapsed = (currentTime - lastTime) * timeScale; cout << timeElapsed << endl; }
und erhalte nun z.b. diese zeiten:
11.5908
11.4006
11.6515
11.4341
11.3817
11.9264
ich stelle fest, dass die erste gemesene zeit nun kürzer als zuvor ist. offenbar profitiert dieser benchmark nun auch von gewissen prozessorinternen optimierungen (wie anwesenheit der daten im L1 cache etc.), zuvor war dieser unangemessen benachteiligt. man kann wohl sagen, dass es keinen signifikanten unterschied zwischen variante 1 und 2 gibt; und auch die dritte variante düfte im rahmen der messgenauigkeit als gleichschnell angesehen werden. wer will, kann ja noch die assembler variante ausprobieren - ist nur eine studie
-
Einfachste Möglichkeit wohl
#include <valarray> // ... if(std::valarray<bool>(array, &array[arraylen]) == true) { // alles true }
Ist grad ungetestet, aber ich denke, dass es so gehen müsste. Die Performance hängt dabei natürlich von der Qualität der valarray-Implementierung ab, und liegt im Zweifel wegen des Kopierens im Konstruktor unter der des Vergleichens des Arrays von Hand, aber wenns dir um die Notation geht...
Ne andere Möglichkeit wäre
#include <set> // ... std::set<bool> tmp_set(array, &array[arraylen]); if(tmp_set.find(false) == tmp_set.end()) { // alles true }
performancetechnisch gilt da aber das gleiche wie für valarray.
-
smasher1985 schrieb:
Nehmt mal bitte Stellung
ok. ich hab mit MinGW compiliert.
Messen ist sauschwer. Aber ich dachte mir schon, daß da was nicht stimmen kann.
Ich messe dies:#include <iostream> typedef unsigned long long u64; #ifdef __MSCVER__ #pragma warning(default:4035) inline u64 rdtsc(){ __asm rdtsc } #pragma warning(disable:4035)//warning C4035: no return value #else inline u64 rdtsc() { u64 tmp; __asm volatile("rdtsc" : "=A" (tmp)); return tmp; } #endif using namespace std; // hier hab ich den ersten Parameter angepasst... inline bool areAllTrue(bool* array,int arrayend){ for(int i=0;i<arrayend;++i) if(!array[i])//wenn einer mit false gefunden wird return false;//dann sind nicht alle true return true;//wenn keine false in der schleife gefunden wurde, sind's true } int g; void foo(){ ++g;//garantier, daß nix wegoptimiert wird } int main() { int const NUM=1000000; bool array[100]; for (int j=0; j<100; ++j) array[j] = (rdtsc()!=0); //garantier, daß der compiler nachher nix wegoptimiert u64 time; /// CAMPERS METHODE 1 time=-rdtsc(); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } time+=rdtsc(); cout <<"Camper1 "<<time<< endl; /// CAMPERS METHODE 2 time=-rdtsc(); { for (int j=0; j < NUM; ++j) { int i = 0;//musste i aus der schlefe nehmen, sonst compiliert's nicht for (; bool( array[ i ] ) && ++i < 100; ); if (i >= 100) { foo(); } } } time+=rdtsc(); cout <<"Camper2 "<<time<< endl; /// VOLKARDS METHODE (leicht verändert) time=-rdtsc(); { for (int j=0; j < NUM; ++j) { if(areAllTrue(array,100)) { foo(); } } } time+=rdtsc(); cout <<"Volkard "<<time<< endl; cout<<'('<<g<<')'<<endl; }
ausgabe:
Camper1 461972848
Camper2 646757321
Volkard 494893179
(3000000)jo, so sind deine messungen.
jetzt lege ich meinen code mal an den anfang, wo unser prozess noch
hohe priorität hat und nicht als langrechner abgestuft wurde.#include <iostream> typedef unsigned long long u64; #ifdef __MSCVER__ #pragma warning(default:4035) inline u64 rdtsc(){ __asm rdtsc } #pragma warning(disable:4035)//warning C4035: no return value #else inline u64 rdtsc() { u64 tmp; __asm volatile("rdtsc" : "=A" (tmp)); return tmp; } #endif using namespace std; // hier hab ich den ersten Parameter angepasst... inline bool areAllTrue(bool* array,int arrayend){ for(int i=0;i<arrayend;++i) if(!array[i])//wenn einer mit false gefunden wird return false;//dann sind nicht alle true return true;//wenn keine false in der schleife gefunden wurde, sind's true } int g; void foo(){ ++g; } int main() { int const NUM=1000000; bool array[100]; for (int j=0; j<100; ++j) array[j] = (rdtsc()!=0); u64 time; /// VOLKARDS METHODE (leicht verändert) time=-rdtsc(); { for (int j=0; j < NUM; ++j) { if(areAllTrue(array,100)) { foo(); } } } time+=rdtsc(); cout <<"Volkard "<<time<< endl; /// CAMPERS METHODE 1 time=-rdtsc(); { for (int j=0; j < NUM; ++j) { bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 100; ); if (allTrue) foo(); } } time+=rdtsc(); cout <<"Camper1 "<<time<< endl; /// CAMPERS METHODE 2 time=-rdtsc(); { for (int j=0; j < NUM; ++j) { int i = 0;//musste i aus der schlefe nehmen, sonst compiliert's nicht for (; bool( array[ i ] ) && ++i < 100; ); if (i >= 100) { foo(); } } } time+=rdtsc(); cout <<"Camper2 "<<time<< endl; cout<<'('<<g<<')'<<endl; }
ausgabe:
Volkard 397708167
Camper1 423422744
Camper2 549747252
(3000000)merke: nur durch erhöhen der anzahl der mesungen erreicht man nicht unbeding eine steigerung
der genauigkeit.am genauesten wird generell gemessen, wenn man von sehr vielen messungen den kleinsten messwert nimmt. denn schneller als ohne störenden fremden einfluss gehts nicht. aber störende einflüsse können auf modernen maschinen so mannigfaltig viele sein, daß man sie beim messen einfach immer mal drin hat.
das führt direkt zu diesem code (bin auf dieses messverfahren sehr stolz):
#include <iostream> typedef unsigned long long u64; #ifdef __MSCVER__ #pragma warning(default:4035) inline u64 rdtsc(){ __asm rdtsc } #pragma warning(disable:4035)//warning C4035: no return value #else inline u64 rdtsc() { u64 tmp; __asm volatile("rdtsc" : "=A" (tmp)); return tmp; } #endif using namespace std; // hier hab ich den ersten Parameter angepasst... inline bool areAllTrue(bool* array,int arrayend){ for(int i=0;i<arrayend;++i) if(!array[i])//wenn einer mit false gefunden wird return false;//dann sind nicht alle true return true;//wenn keine false in der schleife gefunden wurde, sind's true } int g; void foo(){ ++g; } void volkard(bool array[10000]){ if(areAllTrue(array,10000)) foo(); } void camper1(bool array[10000]){ bool allTrue; for( int i = 0; ( allTrue = bool( array[ i ] ) ) && ++i < 10000; ); if (allTrue) foo(); } void camper2(bool array[10000]){ int i = 0;//musste i aus der schlefe nehmen, sonst compiliert's nicht for (; bool( array[ i ] ) && ++i < 10000; ); if (i >= 10000) { foo(); } } u64 measure(void(*f)(bool[10000])){ bool array[10000]; for (int j=0; j<10000; ++j) array[j] = (rdtsc()!=0); u64 minTime=u64(-1); int left=10000; while(left--){ u64 time=-rdtsc(); (*f)(array); time+=rdtsc(); if(time<minTime){ minTime=time; left=10000; } } return minTime; } int main() { cout <<"Volkard "<<measure(&volkard)<< endl; cout <<"camper1 "<<measure(&camper1)<< endl; cout <<"camper2 "<<measure(&camper2)<< endl; cout<<'('<<g<<')'<<endl; }
ausgabe:
Volkard 26404
camper1 26404
camper2 26404
(30008)dann bin ich ins netz gegangen und hab noch ein paarmal gemessen:
Volkard 26389
camper1 26394
camper2 26394
(39654)Volkard 26394
camper1 26394
camper2 26389
(48521)Volkard 26389
camper1 26394
camper2 26389
(63805)wir stellen fest: ich kann sachen mit so grossen laufzeiten nicht auf den takt genau messen. aber den fehler und 1% riegt man schon.
und im rahmen der messgenauigkeit sind alle drei lösungen identisch.
-
interessante lösung - wenns recht ist, benutz ich die in zukunft auch
das ganze nochmal mit vc++7.1 (mal zusätzlich mit der assemblervariante - die ist allerdings nicht ganz optimal)
Volkard 30112
VolkardAsm 6636
camper1 30112
camper2 30112
(30006)nichts besonders ... ganz im gegensatz zu icl 8.1
Volkard 30108
VolkardAsm 6632
camper1 20088
camper2 16788
(37531)
soweit ich das erkennen kann, liegt das daran, dass die volkard version nicht vektorisiert werden kann - das ist eben bei if statements schwierig.edit: es muss übrigens #ifdef _MSC_VER heissen
-
volkard schrieb:
alleTrue &&= array[i];
Sollte das ein Gag sein?
-
camper schrieb:
nichts besonders ... ganz im gegensatz zu icl 8.1
Volkard 30108
VolkardAsm 6632
camper1 20088
camper2 16788
(37531)
soweit ich das erkennen kann, liegt das daran, dass die volkard version nicht vektorisiert werden kann - das ist eben bei if statements schwierig.ka. mag dem argument aber nicht folgen. warum sollten schleifenabbrüche was anderes als if sein? bringt umsortieren wieder was? dann wär's fiesmal schlechtes function alignment.
den faktor 5 für die asm-lösung hab ich mit c++ auch.
inline bool areAllTrueOpt(bool* array,int arrayend){ while(arrayend%8) if(array[--arrayend]) return false; while(reinterpret_cast<size_t>(array)&3) if(!*array++) return false; for(int i=0;i<arrayend/8;++i){ if(((long long*)array)[i++]!=0x0101010101010101ULL) return false; } return true; }
be mir bringen dir 8-er-schritte aber keinen hauch mehr als 4-er-schritte. hab mal 8-er genommen, falls du nen 64-bittigen prozessor hast.