Vitesse des instructions

Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 - 11 avril 2004 à 22:16
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 - 7 mai 2004 à 21:42
Salut,

1- J'aimerais savoir ou trouver la vitesse d'execution des operations elementaires (add, mov, ...) et plus evoluées (sqrtf, cos, ...) .
Pour un processeur AMD.

2- La plupart des processeurs ont une architecture 32-bits, la taille d'un int. Est-il cependant plus rapide de travailler sur des unsigned short int ou des WORD ? (Au fait, c'est quoi la difference entre WORD, short int et unsigned short int ?)

3- Avez-vous des astuces simples pour accelerer un programme ?
Exemple:
Parmi les 2 methodes differentes suivantes pour appeler un membre d'une classe, il y en a bien une plus rapide que l'autre.

------------------------
class deFrancais
{
public:
int nombre;
}

deFrancais *pc_deFrancais;
int n;

n=pc_deFrancais->nombre;
------------------------
class deFrancais
{
protected: (ou private, je ne sais pas la difference)
int nombre;
public:
int getNombre(void) {return nombre;}
}

deFrancais *pc_deFrancais;
int n;

n=pc_deFrancais->getNombre();

Merci

23 réponses

cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
12 avril 2004 à 01:31
private ==> accessible uniquement dans la classe
protected ==> idem mais aussi dans les classes filles

les 2 methode se vale, par defaut un ascesseur defini dans le corps de la classe est inline

sur les machine 32 bits il vaut mieux utiliser le type int ou long qui sont sur 32 bits, mais c'est le type long qui est reelement natif, le type int est fixé dans la norme a 32 bits, donc sur un proco 64 bits il vaut mieux utiliser le long

sinon pour accelerer un programme, ya les fonction inline (macros en c), __fastcall, le design de tes classes joue aussi
je te conseil de redefinir qq fonction de math.h, redefini aussi les conteneur de la stl que tu veux utiliser, deroule tes boucles qd tu peux, faire attention a l'initialisation de tes variable, par ex si tu fait
float x=0; tu perd le temps d'un cast, fait plutot float x=0.0f

utilise memset, memcpy qd tu peux

utilise des decalage binaire qd tu veux diviser/multiplier par 2^n

met les variables les plus utilisées d'un bloc en register (seulement les plus utilisées car elles ne le seront pas tt et il se peut que ce soit fait implicitement par ton compilo)

pour les constructeur de tes classes, initialise les champs avant le corps

struct A
{
int a;

A() : a(0) {}
};

plutot que

struct A
{
int a;

A() { a=0; }
}

sinon les attributs ne seront pa initialiser lors de leur creation

bon la liste est bien sur plus longue, a suivre koi ;)
0
cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 1
13 avril 2004 à 12:55
Whaaa ! Merci djl pour cette ptite liste d'optimisation...
(pkoi ne ferais tu pas un ptit tut ??)

Merci

Bonne prog

Alhexman
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
13 avril 2004 à 21:07
ben vui c'est vrai qu'un petit tuto ca pourrait le faire, mais je me sens pas (encore) capable d'assumer un tel truc, comme je l'ai dit la liste est longue, des connaissance en asm ne sont pas de trop

mais si tu ve enrichir ta culture sur le sujet ya qq truc comme regarder les sources de john carmack ou alors te balader sur les site de game dev & optimisation, comme www.flipcode.com et son forum, nehe (pour l'opengl), www.gametutorials.com ...
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
24 avril 2004 à 23:22
Ok, merci beaucoup djl !

Je vais essayer d'optimiser mon code avec tes astuces.

Sinon est-ce que ca vaut vraiment le coup de programmer en ASM les routines tres souvent appelées.
Car si on connait bien l'assembleur, on peut programmer en C++ en raisonnant en ASM: cad, en faisant en sorte que le compilateur compile le code en C++ comme il l'aurait fait avec l'equivalent en ASM.

EX: favoriser les while aux for.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
25 avril 2004 à 22:02
absolument, prefer les boucle while

utilise aussi les algorithme du c++ quand tu en a besoin, tu pourra pas faire plus optimisé
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
28 avril 2004 à 08:18
Un short est codé sur 2 fois moins de place qu'un int (en 32 bits). Mais est-ce que le processeur execute 2 fois plus rapidement des operations sur des shorts ? (Car plus haut tu as dit qu'il vallait mieux travailler sur des entiers dont la taille est celle de l'architecture du processeur. En gros, dans tous les cas, il faut favoriser les int a tous les autres entiers ???)

Sinon j'ai trouvé ca: http://www.afuu.fr/NEWWEB/afuu/bench/res/compaq/unixware.res.seq.html

Ca peut interresser du monde =-)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
28 avril 2004 à 19:58
utilise le type int, ca correspond a un mot processeur, si tu utilise un short il sera converti en int lors d'une operation donc c'est deja ca de perdu
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
29 avril 2004 à 13:28
Merci beaucoup.
Je vais donc changer tous les short en int (dans mon cas, mieux vaut privilegier la vitesse a la memoire).

A propos d'optimisation:
Comment sont compilées les variables locales aux fonctions?
Sont-elles presentes dans le corps de la fonction, ou juste utilisées via des registres?

ex: (un exemple super con qui ne sert a rien :-))
int pourri(int a)
{
int i = 1000;
int b = 50;
while (i)
{
i--;
a++;
b+=a*i;
}

return b;
}

En assembleur j'aurai fait:
Avec d0 le parametre,

move.w #1000-1,d1
move.w #50,d2
\loop
addq.w #1,d0
move.w d0,d3
mulu.w d1,d3
add.w d3,d2
dbra.s d1,\loop

Ici, d2 est le parametre pour la fonction appelant pourri.

Donc la, aucune variable n'est dans le corps de la fonction.
Est-ce que le compilateur fait de meme?
Sinon, comment le forcer a faire de comme cela?

Merci
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
29 avril 2004 à 20:16
je connais pas l'asm mais je vois ce que tu ve dire

int pourri()
{
int a; // a est declaré sur la pile
// sa duree de vie est celle de la fonction

static int b; // b est static, il se trouve
// dans la zone de donnée (je crois) et sa
// duree de vie est celle du programme
// cependant sa visibilite est celle de la
// fonction pourri

register int c; // c est declaré dans un registre du
// processeur, le top au niveau de l'acces, mais
// sera reelement dans le registre seulement si ill y
// a de la place
}

note : en C (ansi et pre ansi) le type par defaut est int donc les ecritures

static i; ou
register i; sont supporte, c'est juste equivalent a

static int i;
register int i;
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
29 avril 2004 à 20:18
j'ai oublie, le static doit etre initialiser a sa declaration

static int b=0;
0
cs_AlexMAN Messages postés 1536 Date d'inscription samedi 21 décembre 2002 Statut Membre Dernière intervention 24 mai 2009 1
30 avril 2004 à 19:40
djl, ta derniere remarque est pas fausse mais inutilee, car toutes les variables de classe d'allocation statique sont initialisées a leur declaration avec la valeur 0...Je veux pas dire de betises, c'est tout de mm a vérifier...

++
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
30 avril 2004 à 20:07
tout a fait, j'ai confondu avec membre static d'une classe (desole)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
30 avril 2004 à 20:10
tout a fait, j'ai confondu avec membre static d'une classe (desole)
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
2 mai 2004 à 01:07
Merci pour vos réponses et les precisions !

Quand on compile en Release, on peut choisir le mode "Maximun Speed". Le compilateur cherche donc à optimser le programme en vitesse, met-il automatiquement les variables les plus utilisées en registres ? Ou que fait-il de particulier par rapport aux autres modes ? Il ne modifie pas l'algorithme quand meme...
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
2 mai 2004 à 01:07
Merci pour vos réponses et les precisions !

Quand on compile en Release, on peut choisir le mode "Maximun Speed". Le compilateur cherche donc à optimser le programme en vitesse, met-il automatiquement les variables les plus utilisées en registres ? Ou que fait-il de particulier par rapport aux autres modes ? Il ne modifie pas l'algorithme quand meme...
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
2 mai 2004 à 23:46
non il ne modifie pas l'algorithme,je sais juste qu'en debug ta plus de memoire pour les données du process (pour prevenir les debordement)

quand aux optimisation, elles sont presente sur tout les compilo, faut donc regarder la doc. certain compilo sont reputé pour pour ca, tel que watcom c++
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
5 mai 2004 à 20:04
C'est louche, j'avais posté un mail je ne sais plus trop quand pour repondre au dernier message (celui du 02/05/2004 23:46:05 de djl), tout s'etait bien deroulé: message envoyé, mais le message n'est pas passé. Par contre, ca a posté le dernier message que j'avais tapé, juste derriere ce dernier (d'ou mon message en double)!

Je ne me suis pas amusé a poster le meme message avec 12 min d'ecart quand meme!

Bon, tant pis... je recommence.

Merci djl de répondre a toutes mes questions pas forcement palpitantes :-) !

Mais j'ai toujours des problemes :-) (de moins en moins, faut se dire ca).

Dans mes programmes, j'utilise tres souvent (plusieurs 10n de milliers de fois par boucle), point[i]->

Donc le pointeur se tape une addition *(point + i) un nombre enorme de fois, alors qu'il suffirait de le calculer une fois pour toute.

Pour accelerer mon programme, j'ai essayé:

(VOID*) pointeur;

pointeur = point + i;

pointeur-> au lieu de point[i]->

Mais ca marche pas. Que faire ?

Merci
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
5 mai 2004 à 20:45
ben non tes questions sont interessantes je trouve, et pertinantes

oui point[i] <=> *(point + i ) et aussi i[point] mais c'est deja moins lisible

tu utilise l'operateur -> donc point est un tableau de pointeur par contre je sais pas de quel type mais dans tout les cas tu sera quand mem obligé de le deferencer

voila un exemple (en c++)

#include 

struct Foo
{   
    static unsigned count;
    void bar()
    {
        std::cout << "Foo numero " << ++count << '\n';
    }
};
unsigned Foo::count =0;

int main()
{
    const size_t SIZE=20;
    Foo *tab[SIZE];
    
    for(size_t i=0;i<SIZE;i++)
    {
        tab[i]=new Foo;
    }
    
    Foo **cur=(Foo **)tab;
    
    for(size_t i=0;i<SIZE;i++)
    {
        (*cur)->bar();
        cur++;
    }
    
    
    for(size_t i=0;i<SIZE;i++)
    {
        delete tab[i];
    }
    
    std::cout.flush();
    std::cin.get();
}


quoiqu'il en soit, tu a du le remarquer, ca revien au meme finalement, donc on peut conclure que [] fait tres bien son boulot ?
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
5 mai 2004 à 20:47
tu peux faire direct (*cur++)->bar(); c'est pareil
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
7 mai 2004 à 21:07
Ok, merci ca marche !

Ca optimise pas des masses .... 3-5% je dirais, c'est deja ça !

C'est vrai, c'est plus facile de definir le pointeur avec la classe qu'il pointe sans utiliser les VOID.
Mais ainsi créé, le pointeur n'est pas un vrai pointeur car il ne peut pointer qu'un type de classe.

Le tres maigre avantage du C++ sur les pointeurs, c'est que lorsqu'on fait pointeur++, on se deplace dans la memoire de la taille de la classe, et pas de 1 octet comme en assembleur.

Revenons a nos moutons, si je veux definir un pointeur dont je ne connais pas le type a l'avance, il faut utiliser un VOID C'est ce qui est fait dans la classe CCube, partie creation de vertices:

VOID* pVertices;

[...]

g_pVertices->Lock(0, sizeof(cvVertices), (BYTE**)&pVertices, 0);

Mais comment transformer un pointeur VOID en un pointeur vers une classe?
0
Rejoignez-nous