Déclarer les variables derrière la boucle ou à l'intérieur de la boucle ? - page 10

 
Vict:

temps = 1018
somme = 894782460
temps = 371
somme = 894782460

Je ne sais pas pourquoi, mais µl le dépasse (ainsi que les variantes plus complexes de rand()).

Et pour moi, c'est évident - le retirer de la boucle.

Oui, vous avez raison, j'ai essayé dans VS aussi et pour une raison quelconque, cela n'a pas optimisé du tout, bien qu'une variante aussi simple semble... En fait, cela revient à ceci :

char *st = new char[23];
memcpy(st, "12345678qwertyuioasdfgh", 23);
sum += st[i % 23];
delete[] st;
 
Alexey Navoykov:

Oui, vous avez raison, j'ai essayé dans VS aussi - pour une raison quelconque, ce n'est pas optimisé du tout, bien qu'il s'agisse d'une option si simple, il semblerait... En substance, cela revient à ceci :

Êtes-vous sûr d'avoir activé toutes les optimisations dans les paramètres du projet? Dans des cas étranges, j'allume la génération de la liste d'assemblage et je la regarde, c'est très instructif.

 

J'ai décidé de le tester également en C# par curiosité. Non seulement les résultats sont presque les mêmes en termes de vitesse, mais ils fonctionnent également beaucoup plus rapidement qu'en C++.

public class Program
{
  public static void Main()
    {
        int count = (int)10 e6;

        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            int sum = 0;
            for (int i = 0; i < count; i++)
            {
                string st;
                st = "12345678qwertyuioasdfgh";
                sum += st[i % 23];
            }
            Console.WriteLine("Sum: {0}, Time: {1} ms", sum, watch.ElapsedMilliseconds);
        }

        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            int sum = 0;
            string st;
            for (int i = 0; i < count; i++)
            {
                st = "12345678qwertyuioasdfgh";
                sum += st[i % 23];
            }
            Console.WriteLine("Sum: {0}, Time: {1} ms", sum, watch.ElapsedMilliseconds);
        }

        Console.ReadKey();
    }
}

Résultats :

Somme : 894782460, Temps : 69 ms.

Somme : 894782460, Temps : 56 ms

Et voici un analogue en C++ :

Somme : 894782460, Temps : 2947 ms

Somme : 894782460, Temps : 684 ms

Je le teste dans VS 2019,toutes les optimisations sont activées .

Au diable un tel C++.)

p.s. Les résultats en C# varient agréablement d'un test à l'autre, mais en moyenne les deux variantes sont aussi rapides l'une que l'autre.

 
Alexey Navoykov

Vous devez d'abord comprendre les raisons de ces freins. J'ai fait un peu de recherche, et tout est en ligne sauf l'appel.

0x41a727 <main()+119>   callq  0x48e1a0 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEmmPKcm>

qui se trouve dans libstdc++. C'est-à-dire qu'à l'arrière-plan de la boucle presque nue, le goulot d'étranglement est constitué par les appels de fonction eux-mêmes (et il y a aussi quelques appels de ...replaceEmmPKcm). Le compilateur peut optimiser dans une seule unité de traduction. Vous pouvez essayer d'utiliser LTO (link time optimization), c'est-à-dire que cela permet d'optimiser l'étape de liaison. Mais je ne l'ai pas utilisé, je ne le ferai pas maintenant. Eh bien, il n'y a rien de particulièrement compliqué - passer à l'option -flto du compilateur/linker (mais il me manque un plugin), trop paresseux pour le découvrir + il faudra peut-être reconstruire libstdc++.

Comment cela se passera-t-il avec l'optimisation du code en relation avec le vissage des modules à venir (depuis C++20) ? Je ne sais pas, vous pouvez essayer en vs, bien que tout soit brut et expérimentalhttps://habr.com/en/company/pvs-studio/blog/328482/

c++'u va nous manquer ;)).

Использование модулей C++ в Visual Studio 2017
Использование модулей C++ в Visual Studio 2017
  • habr.com
Команда Visual C++ рада сообщить, что в Visual Studio 2017 было существенно улучшено качество реализации модулей C++ согласно технической спецификации; также мы добавили возможность подключать Стандартную Библиотеку C++ через интерфейсы модулей. Эти интерфейсы, как и поддержка модулей компилятором, являются экспериментальной разработкой и будут...
 
Alexey Navoykov:

Par souci d'intérêt, j'ai décidé de tester également en C#. Non seulement les résultats sont presque identiques en termes de vitesse, mais ils sont également plus rapides d'un ordre de grandeur par rapport au C++.

Résultats :

Somme : 894782460, Temps : 69 ms

Somme : 894782460, Temps : 56 ms

Et voici un analogue en C++ :

Somme : 894782460, Temps : 2947 ms.

Somme : 894782460, Temps : 684 ms

Je le teste dans VS 2019,toutes les optimisations sont activées .

Au diable un tel C++.)

p.s. Les résultats en C# fluctuent considérablement d'un test à l'autre, mais en moyenne les deux variantes sont égales en vitesse.

Br-r-r-r-r, pas question ! Sharp a toujours battu les vrais pros par un facteur de deux, mettez le projet en route, s'il vous plaît.

 

Petits enfants :)

Ils ont étiré le jouet à 10 pages...

 
Vict:

Il faut d'abord comprendre les raisons de la lenteur. J'ai creusé un peu et tout est en ligne, sauf l'appel.

qui se trouve dans libstdc++.

Il semble donc avoir compris qu'il alloue et supprime la mémoire à chaque fois, même dans ce cas :

char *str = new char[23];
...
delete str;


Au fait, j'ai peut-être donné des résultats erronés la dernière fois. C'était probablement en mode x86. Je teste maintenant en mode x64 et les résultats par C++ sont bien meilleurs :

1) ~ 2000 msec

2) ~ 200 ms (c'est 3 fois plus rapide).

Bien que j'aie également mis à jour Studio à la dernière version, cela a dû l'influencer aussi puisque même x86 est plus rapide maintenant que les tests précédents.

Maintenant, le C++ n'est plus aussi honteusement en retard sur le Sharp, mais seulement de trois fois environ.)

 
Alexey Navoykov:

Il semble donc avoir compris qu'il alloue et supprime la mémoire à chaque fois, même dans ce cas :


Au fait, j'ai peut-être donné de mauvais résultats la dernière fois. C'était probablement en mode x86. Je teste maintenant en mode x64 et les résultats par C++ sont bien meilleurs :

1) ~ 2000 msec

2) ~ 200 ms (c'est 3 fois plus rapide).

Bien que j'aie également mis à jour Studio à la dernière version, cela a dû l'influencer aussi puisque même x86 est plus rapide maintenant que les tests précédents.

Eh bien, maintenant, le C++ ne perd plus aussi honteusement contre le Sharp. Seulement par 3 fois environ ;)

vous ne comprenez pas, ce n'est pas ce que je veux dire. En général, le test est un jouet - une boucle simple sans charge utile. J'ai essayé de vous dire que les pertes sur les appels de fonction, qui ne peuvent pas être en ligne. Un meilleur test plus des modules, des résultats plus intéressants, même s'ils sont encore peu développés.
 
Alexey Volchanskiy:

Brrr-r-rr, pas question ! Sharp a toujours été deux fois plus performant que les plus propres, tu sors le projet plz.

Dossiers :
Project1.zip  1671 kb
 
Vict:
Il vaut mieux tester les modules plus, les résultats y sont plus intéressants, bien qu'ils puissent encore être non documentés.

J'ai vérifié, il s'avère qu'aucun compilateur https://en.cppreference.com/w/cpp/compiler_support n'a terminé les modules, donc il n'y a rien à voir.

Raison: