Les trois derniers appels de méthode prennent env. doubler le temps que les quatre premiers. La seule différence est que leurs arguments ne tiennent plus en nombre entier. Mais cela devrait-il être important? Le paramètre est déclaré long, il doit donc être long pour le calcul. Est-ce que l'opération modulo utilise un autre algorithme pour les nombres> maxint? J'utilise amd athlon64 3200+, winxp sp3 et vs2008.Comportement de comportement étrange pour un fonctionnement modulo 64 bits
Stopwatch sw = new Stopwatch();
TestLong(sw, int.MaxValue - 3l);
TestLong(sw, int.MaxValue - 2l);
TestLong(sw, int.MaxValue - 1l);
TestLong(sw, int.MaxValue);
TestLong(sw, int.MaxValue + 1l);
TestLong(sw, int.MaxValue + 2l);
TestLong(sw, int.MaxValue + 3l);
Console.ReadLine();
static void TestLong(Stopwatch sw, long num)
{
long n = 0;
sw.Reset();
sw.Start();
for (long i = 3; i < 20000000; i++)
{
n += num % i;
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
EDIT: je maintenant essayé la même chose avec C et la question ne pas se produit ici, toutes modulo opérations prennent en même temps, dans la version et en mode débogage avec et sans optimisations activées:
#include "stdafx.h"
#include "time.h"
#include "limits.h"
static void TestLong(long long num)
{
long long n = 0;
clock_t t = clock();
for (long long i = 3; i < 20000000LL*100; i++)
{
n += num % i;
}
printf("%d - %lld\n", clock()-t, n);
}
int main()
{
printf("%i %i %i %i\n\n", sizeof (int), sizeof(long), sizeof(long long), sizeof(void*));
TestLong(3);
TestLong(10);
TestLong(131);
TestLong(INT_MAX - 1L);
TestLong(UINT_MAX +1LL);
TestLong(INT_MAX + 1LL);
TestLong(LLONG_MAX-1LL);
getchar();
return 0;
}
EDIT2:
Merci pour les excellentes suggestions. J'ai trouvé que les deux. Net et C (en mode de débogage ainsi que dans le mode de libération) n'utilisent pas atomiquement les instructions cpu pour calculer le reste, mais ils appellent une fonction qui le fait.
Dans le programme c je pourrais obtenir le nom de celui-ci qui est "_allrem". Il a également affiché des commentaires de source complète pour ce fichier, donc j'ai trouvé l'information que cet algorithme spécial cas les diviseurs 32 bits au lieu de dividendes, ce qui était le cas dans l'application. J'ai également découvert que la performance du programme c est vraiment seulement affectée par la valeur du diviseur, mais pas le dividende. Un autre test a montré que la performance de la fonction restante dans le programme .net dépend à la fois du dividende et du diviseur. BTW: Même des ajouts simples de longues valeurs longues sont calculés par des instructions add et adc consécutives. Donc, même si mon processeur lui-même appelle 64bit, il est vraiment pas :(
EDIT3:
maintenant je courais l'application c sur un ordinateur Windows 7 édition 64 bits, compilé avec Visual Studio 2010. La chose drôle est le comportement de la performance reste le même, bien que maintenant (j'ai vérifié la source d'assemblage) vraies 64 instructions de bits sont utilisés.
En ce qui concerne votre dernière observation, si vous utilisez Windows XP, vous êtes presque certain que vous utilisez votre processeur 64 bits en mode 32 bits. – caf
Votre processeur est en réalité en 64 bits, c'est votre système d'exploitation et votre compilateur qui fonctionnent en mode 32 bits. –