• [^] # Re: Sans SSE

    Posté par (site web personnel) . En réponse au journal Recherche de valeur dans un tableau et l'écosystème des compilateurs C++. Évalué à 1. Dernière modification le 08 octobre 2021 à 14:40.

    Sur ARM (un chromebook avec Debian dessus), j'obtiens de meilleurs score pour la version "CMOV" sur le main que j'ai mis au-dessus, les valeurs sont loader bien avant le CMOV, donc pas besoin de prédiction de valeur, elles sont dispo lors du cmov (il faudrait faire du profiling, j'ai la flème).

    $ ./test.x
    C1 = 928197 (499999984), C2 = 605687 (499999984), C3 = 538721 (499999984), C4 = 539927 (499999984), C5 = 545717 (499999984)

    C3 et C4 sont 2 versions CMOV, les autres utilisent les branchements. C5, c'est le code que tu as mis dans l'autre commentaire.

    $ cat /proc/cpuinfo 
    processor : 0
    BogoMIPS : 26.00
    Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
    CPU implementer : 0x41
    CPU architecture: 8
    CPU variant : 0x0
    CPU part : 0xd03
    CPU revision : 4
    [ . . . 8 cores qui semblent identiques ]
    size_t find_int_c3(const int k, const int* v, const size_t n) {
     unsigned int mask = 0;
     size_t i = 0;
     for (; i < n - 8;) {
     mask = v[i] != k ? mask : 1;
     mask = v[i+1] != k ? mask : 2;
     mask = v[i+2] != k ? mask : 4;
     mask = v[i+3] != k ? mask : 8;
     mask = v[i+4] != k ? mask : 16;
     mask = v[i+5] != k ? mask : 32;
     mask = v[i+6] != k ? mask : 64;
     mask = v[i+7] != k ? mask : 128;
     i += 8;
     if (mask != 0) i += n;
     __builtin_prefetch(v + i + 512, 0, 1);
     }
     i -= n + 8;
     if (mask == 0) return n;
     if (mask == 1) return i;
     if (mask == 2) return i + 1;
     if (mask == 4) return i + 2;
     if (mask == 8) return i + 3;
     if (mask == 16) return i + 4;
     if (mask == 32) return i + 5;
     if (mask == 64) return i + 6;
     if (mask == 128) return i + 7;
    }
    size_t find_int_c4(const int k, const int* v, const size_t n) {
     size_t i = 0;
    // size_t n2 = n >> 1;
    // const long* vl = (const long*)v;
    // const long kl = (long)(((long)k>>32) + k);
     unsigned int index = 0;
     for (; i <= n; i += 8, v += 8) {
     index = 0;
     __builtin_prefetch(v + 256);
     index = v[0] != k ? index : 1;
     index = v[1] != k ? index : 1;
     index = v[2] != k ? index : 1;
     index = v[3] != k ? index : 1;
     index = v[4] != k ? index : 1;
     index = v[5] != k ? index : 1;
     index = v[6] != k ? index : 1;
     index = v[7] != k ? index : 1;
     if (index == 1) {
     break;
     }
     }
     if (index == 0) return i;
     else
     for (int j = 0; i < 8; j++) {
     if (v[j] == k) return i + j;
     }
    }
    size_t find_int_c5(const int k, const int* v, const size_t n) {
     size_t i = 0;
     for (; n - i >= 8; i += 8,v+=8)
     {
     __builtin_prefetch(v+256); //54/148
     if (v[0] == k) return i;
     if (v[1] == k) return i + 1;
     if (v[2] == k) return i + 2;
     if (v[3] == k) return i + 3;
     if (v[4] == k) return i + 4;
     if (v[5] == k) return i + 5;
     if (v[6] == k) return i + 6;
     if (v[7] == k) return i + 7;
     }
     for (; i != n; i++,v++)
     if (v[0] == k)
     return i;
     return n;
    }

    Le fait que C3 soit plus rapide que C4 est contre-intuitif, mais le prefetch n'est pas placé aux mêmes endroits. Je m'attendais à de plus de différences...

    Perso j'adore ce Chromebook, pour 250 EUR t'as un Linux sur ARM (certes, ça ne vaut pas un RPi). Mais il y a un très bon écran.