Donc, au lieu de x*3, il fait x+x+x. Or un décalage d'un bit sur la gauche est plus rapide qu'une addition.
Donc, pour O0, il vaut mieux la micro-optimisation.
Pour O1, O2 et O3, je dois admettre ne pas comprendre le fonctionnement : ils utilisent LEA, que je ne comprends pas (par ailleurs, je note qu'il me semble que O2 et O3 ajoutent des instructions par rapport à O1, sans en enlever aucune).
Mais, dans au moins un cas, il est préférable de faire la micro-optimisation, et dans les autres on n'y perd rien. Donc j'ai gagné, et j'ai un bénéfice de 1 nanoseconde !
Si tu compiles en -O0 (des gens font ça?! ) tu compiles pas pour les perfs et donc tu sors pas des tricks de sioux. En résumé tu obfusques une opération élémentaire pour un gain négligeable effectif que dans un seul mode de compilation? J'appelle pas ça gagner :).
Fin bref, de toute façon, c'est un cas isolé et simple, sur des choses bien plus compliqué y'a peu de chance que tu fasses mieux que le compilo dans le cas scalaire en tout cas et si tu y'arrives ça sera au prix de la lisibilité.
Mais vraiment, au delà de la mesure de cycle gagné/perdu l'argument de poids c'est la lisibilité et la simplicité de tes sources.
Pour O1, O2 et O3, je dois admettre ne pas comprendre le fonctionnement : ils utilisent LEA, que je ne comprends pas (par ailleurs, je note qu'il me semble que O2 et O3 ajoutent des instructions par rapport à O1, sans en enlever aucune).
Quand tu compiles vers l'assembleur, utilise plutôt le format Intel (option "-masm=intel" pour gcc), il est beaucoup plus clair que le format AT&T:
(gdb) file a0
Reading symbols from /tmp/a0...(no debugging symbols found)...done.
(gdb) disas op
Dump of assembler code for function _Z2opi:
0x0000000000000000 <+0>: push %rbp
0x0000000000000001 <+1>: mov %rsp,%rbp
0x0000000000000004 <+4>: mov %edi,-0x4(%rbp)
0x0000000000000007 <+7>: mov -0x4(%rbp),%edx
0x000000000000000a <+10>: mov %edx,%eax
0x000000000000000c <+12>: add %eax,%eax
0x000000000000000e <+14>: add %edx,%eax
0x0000000000000010 <+16>: pop %rbp
0x0000000000000011 <+17>: retq
End of assembler dump.
(gdb) file b0
Reading symbols from /tmp/b0...(no debugging symbols found)...done.
(gdb) disas op
Dump of assembler code for function _Z2opi:
0x0000000000000000 <+0>: push %rbp
0x0000000000000001 <+1>: mov %rsp,%rbp
0x0000000000000004 <+4>: mov %edi,-0x4(%rbp)
0x0000000000000007 <+7>: mov -0x4(%rbp),%eax
0x000000000000000a <+10>: add %eax,%eax
0x000000000000000c <+12>: add -0x4(%rbp),%eax
0x000000000000000f <+15>: pop %rbp
0x0000000000000010 <+16>: retq
End of assembler dump.
On peut noter qu'il n'y a que, dans le calcul lui-même, des instructions mov et add dans les deux cas.
Le calcul -0x4(%rbp) est présent 3 fois dans le b, 2 dans le a. Petit avantage pour a, donc, ici.
Mais b a un mov de moins, ce que je pense (peut-être à tort ?) plus important.
De toute façon, peu importe O0.
Pour O1, O2 et O3, on peut noter que le code généré est strictement identique.
Donc c'est une partie d'échecs qui se termine en ex-aeco.
Si tu compiles, puis que tu désassembles, -masm=intel ne sert pas à grand chose
Utilise l'option -S au lieu de -c pour obtenir le code source assembleur (toujours dans le fichier indiqué par -o): g++ -masm=intel -S a.cpp -o a0 -O0
Pour avoir le même format sous gdb, il faut utiliser set disassembly-flavor intel.
tu gagnerais si on vivait dans les années 60. De nos jours ton compilo est bien plus efficace que toi pour faire ce genre de chose et le fera mieux et sûrement même plus agressivement.
Tu as un peu forcé le trait là.
Ce genre d'opti était encore très, très utilisé dans les années 90.
voila j'ai fini la correction de l'exo "Tic-Tac-Toe", avec les corrections. Voici :
main.cpp :
#include <iostream>
#include <cstdlib>
#include "grille.h"
using namespace std;
int main()
{
Grille g;
int choix = 0;
cout << "bienvenu dans ce Tix-Tac-Toe, voici la grille numérotée" << endl;
g.afficher();
g.init();
while(1)
{
cout << "c'est à '" << g.next() << "' de jouer" << endl;
do
{
choix = 0;
cout << "quel est votre choix '" << g.next() << "' ?" << endl;
cin >> choix;
}while(!g.playAt(choix));
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
g.afficher();
if(g.won() == 'e' || g.won() == 'x' || g.won() == 'o')
break;
}
if(g.won() == 'e')
cout << "egalité !!!" << endl;
else
cout << g.won() << " a gagné la partie" << endl;
return 0;
}
grille.h :
#ifndef GRILLE_H
#define GRILLE_H
#include <iostream>
class Grille
{
public:
Grille(char starting = 'o');// génère la grille remplit par défaut par les nombre 1, 2, 3, ..., 7, 8, 9
void afficher();// affiche la grille
void init();// initialise toute les cases de m_grille à ' '
bool playAt(int x, int y = -1);// soit les coordonnées de m_grille, soit un nombre entre 1 et 9
char won();// 0 si personne, 1 si o, 2 si x
char next();
private:
char m_grille[3][3];// la grille
char m_next;// le prochain "joueur" à jouer : 'o' ou 'x'
};
#endif
pas si lourd que sa (dans la tête du compilateur ) il appelle une première fois la fonction. Si elle est vérifier, il ne se casse plus la tête et va donc lire la suite. sinon, il lis l'autre appelle de la fonction etc... (de mon point de vue )
Je pense que tu peux faire mieux pour certain truck comme :
if(Player1Play) //If it was the player 1's turn
Player1Play = false; //Now it's the turn of player 2
else if(!Player1Play) //If it was the player 2's turn
Player1Play = true; //Now it's the turn of player 1
Ou :
if(((Player1Boxes.at(0) && Player1Boxes.at(4) && Player1Boxes.at(8))) || // If
(Player1Boxes.at(0) && Player1Boxes.at(3) && Player1Boxes.at(6)) || // Player
(Player1Boxes.at(0) && Player1Boxes.at(1) && Player1Boxes.at(2)) || // 1
(Player1Boxes.at(1) && Player1Boxes.at(4) && Player1Boxes.at(7)) || // Straits
(Player1Boxes.at(2) && Player1Boxes.at(4) && Player1Boxes.at(6)) || // 3
(Player1Boxes.at(2) && Player1Boxes.at(4) && Player1Boxes.at(8)) || // Boxes,
(Player1Boxes.at(3) && Player1Boxes.at(4) && Player1Boxes.at(5)) || // He
(Player1Boxes.at(6) && Player1Boxes.at(7) && Player1Boxes.at(8))) // Win
{
end = true; Player1Win = true; Player2Win = false; ToReturn = 1;
} //It's the end, the player 1 win, the player 2 didn't won, we return 1
else if(((Player2Boxes.at(0) && Player2Boxes.at(4) && Player2Boxes.at(8))) || // If
(Player2Boxes.at(0) && Player2Boxes.at(3) && Player2Boxes.at(6)) || // Player
(Player2Boxes.at(0) && Player2Boxes.at(1) && Player2Boxes.at(2)) || // 2
(Player2Boxes.at(1) && Player2Boxes.at(4) && Player2Boxes.at(7)) || // Straits
(Player2Boxes.at(2) && Player2Boxes.at(4) && Player2Boxes.at(6)) || // 3
(Player2Boxes.at(2) && Player2Boxes.at(4) && Player2Boxes.at(8)) || // Boxes,
(Player2Boxes.at(3) && Player2Boxes.at(4) && Player2Boxes.at(5)) || // He
(Player2Boxes.at(6) && Player2Boxes.at(7) && Player2Boxes.at(8))) // Win
{
end = true; Player2Win = true; Player1Win = false; ToReturn = 2;
} //It's the end, the player 2 win, the player 1 didn't won, we return 2
Aussi, on peut écrire sur une case ou il y a déjà un nombre, pratique
Pour finir :
X | O | X
---+---+---
X | O | O
---+---+---
O | X | X
Please enter the number of your choice :
Bonne chance
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
if(Player1Play) //If it was the player 1's turn
Player1Play = false; //Now it's the turn of player 2
else if(!Player1Play) //If it was the player 2's turn
Player1Play = true; //Now it's the turn of player 1
Peut simplement devenir : Player1Play=!Player1Play;
Le deuxième, je pense que cela vient de la structure même de ton code.
Pour le reste, j'avoue ne pas avoir le courage de regarder le tout.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
Comme vous aimez bien l'OO, je vous ai concocté un truc spécialement fait en OO, et dont toutes les fonctionnalités méritant de l'être le sont.
J'ai même fait un petit diaramme de dépendance, pour prouver qu'il n'y a pas de couplage trop fort entre deux classes. (Bon, le diagramme de dépendance m'a pris plus de temps que le code, mais c'est à la fois parce que je suis nul en dessin, que je découvrais inkscape, et que je ne connais aucun vrai programme d'édition d'UML : BoUML, j'ai essayé de m'en servir, j'ai abandonné. Il me semble qu'à une époque j'avais utilisé quelque chose comme graphviz, mais je ne me souviens plus de comment faire précisément.)
Voici tout ce que j'ai fait :
Il est à noter que, puisque chaque flèche ne pointe que vers un élément plus haut que son origine (même si ce n'est pas toujours très visible), il n'y a pas de couplage fort.
Voici, maintenant, le code source (à noter : il y a quelques bouts de c++11 dont je me suis servi) :
main.cpp :
#include <vector>
#include "Plate.hpp"
#include "Player.hpp"
#include "PlayerFactory.hpp"
#include "User.hpp"
typedef std::vector<PlayerPtr> PlayerList;
int main(int, char**) {
PlayerList players;
Plate plate;
int nbPlayers = User::AskNbPlayers();
while (--nbPlayers >= 0) {
players.push_back(PlayerFactory::CreateConsolePlayer());
}
PlayerPtr winner;
bool stop;
while (!stop) {
for (PlayerPtr & p : players) {
User::DisplayPlate(plate);
plate.Play(p->Play(plate), p->Code());
if (plate.Ended()) {
winner = p;
stop = true;
break;
}
}
}
User::DisplayPlate(plate);
if (plate.ExAeco()) {
User::ExAeco();
} else {
User::Winner(winner);
}
return EXIT_SUCCESS;
}
Euh ... C'est-à-dire que ... En fait ... Bah ...
C'est une assiette de morpion !
En fait, si on veut être précis, ce que je dessine c'est une plaque.
Parce que, après tout, il n'y a pas de champ de morpion.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.