Mon livre de chevet, Unleashed C (non je mens, mon livre de chevet reste Playboy, mais ça fait moins sérieux), propose d'implémenter une FIFO (ou "pipe", pour tube en anglais) de la façon suivante (approximativement, j'ai simplifié la représentation (surtout il y avait QUEUE
écrit et je veux pas de problèmes)) :
+----------+
| taille |
+----------+
| debut |-------+
+----------+ |
| fin | |
+----------+ V
| +---+---------+
| | s | donnes |
| +---+---------+
| |
| V
| +---+---------+
+------------->| s | donnes |
+---+---------+
|
V
NULL
Avec, bien entendu, plein de code C manipulant des pointeurs (que j'aime :D).
Moi je veux une petite FIFO. Une pouvant contenir 4 caractères (voir 8) ; la version du livre est un peu gore dans ce cas.
Une FIFO, on pousse à droite, ça sort à gauche. On pousse à droite … ça me rappelle un opérateur : <<
. Je prends une variable, pouvant contenir des valeurs de 4 ou 8 octets, une variable pour compter et j'ai une FIFO. Rudimentaire mais suffisante !
Donc ma FIFO commence sa vie avec une structure :
/* Ne pas déraper, ne pas déraper, ... */
typedef struct s_small_dick { /* /o\ */
unsigned char count;
uint32_t data; /* uint64_t pour 8 caracteres */
} SmallFifo;
Ensuite il faut quelques fonctions pour la faire vivre. D'abord l'initialisation (pour la forme) :
void sf_init(SmallFifo * f)
{
if(f==NULL) return;
f->count=0;
f->data=0;
return;
}
Ensuite je veux pouvoir ajouter des valeurs. Cette opération est d'une simplicité déconcertante.
void sf_push(SmallFifo * f, unsigned char b)
{
if(f==NULL) return;
/* C'est une FIFO qui, si elle est pleine, éliminent les valeurs les plus
* anciennes (pas conseillé pour la retraite ^^).
*/
f->data=(f->data<<8)|b;
if(f->count<sizeof(f->data)) f->count++;
}
Pour récupérer les valeurs, nous allons, très simplement, appliquer la méthode suivante :
unsigned char sf_pop(SmallFifo * f)
{
if(f==NULL) return 0x00;
/* Pas tomber trop bas */
if(f->count>0) f->count--;
return (unsigned char)(f->data>>(8 * f->count)) & 0xFF;
}
Et, pour la forme, une fonction qui retourne une valeur différente de 0 s'il y a encore des données dans notre FIFO :
unsigned char sf_has_data(SmallFifo * f)
{
if(f==NULL) return 0x00;
if(f->count>0) return 0xEB; /* mes initiales \o/ */
return 0x00;
}
Bien entendu, ce code n'a été que brièvement testé et contient, peut-être, des erreurs.
int main(int argc, char ** argv)
{
SmallFifo ma_fifo;
char des_valeurs[]="abcdefghijklmnopqrstuvwxyz";
int i=0; /* un compteur */
sf_init(&ma_fifo);
for(i=0;i<4;i++) {
sf_push(&ma_fifo, des_valeurs[i]);
}
while(sf_has_data(&ma_fifo)) {
printf("%c ", sf_pop(&ma_fifo));
}
printf("\n");
for(i=0;i<26;i++) {
sf_push(&ma_fifo, des_valeurs[i]);
}
while(sf_has_data(&ma_fifo)) {
printf("%c ", sf_pop(&ma_fifo));
}
printf("\n");
return 0;
}
Pour tester ce code, n'oubliez pas d'inclure stdint.h
ou alors changer le type en unsigned long int
, ça devrait faire 4 octets même sur un AVR ou un PIC.
PS: Si, par mégarde, j'ai choqué une femme dans ce journal, j'en suis désolé. Pour me faire pardonner, j'accepterais jusqu'aux châtiments corporels, y compris être tuer et violer tant que ça reste dans cet ordre là (sauf ma copine, halle_berry.jpeg
, qui peut le faire dans l'ordre inverse).
# Constante invalide
Posté par Obsidian . Évalué à 10.
Moi, je lis « Enormous Boobs ». C'est sexiste ! Je te demande de changer de constante.
Quand tu fais ceci, tu récupères l'octet situé à la position « count », mais tu n'effaces pas le contenu de « data », et tu ne tiens pas compte du fait non plus que ta file peut être vide (sauf pour la gestion de « count »). Ça veut dire d'une part que si tu continues à dépiler une file vide, tu vas obtenir à chaque fois la dernière valeur dépilée qui peut être non nulle.
Puisque tu utilises déjà des opérateurs de décalage sur des registres du même format, pourquoi ne t'en sers-tu pas pour décaler directement le contenu de ta file ?
[^] # Re: Constante invalide
Posté par Etienne Bagnoud (site web personnel) . Évalué à 1.
Bien vu. je n'y avais pas penser. Merci :)
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Constante invalide
Posté par MCMic (site web personnel) . Évalué à 10.
Alors, tu remplace le verbe par mordre, et si ça donne "mordu", tu met un "é" à la place du er. Ça fonctionne à la fois dans les commentaires et les journaux ("être tuer et violer" => "être mordu et mordu", donc "être tué et violé")
PS : Pour le reste des conjugaisons, je te laisse te renseigner, mais il y a d'autres règles, et "C'est une FIFO qui […] éliminent les valeurs" confirme que "ce code […] contient, peut-être, des erreurs."
[^] # Re: Constante invalide
Posté par Etienne Bagnoud (site web personnel) . Évalué à 3.
Ah non ! là tu as une LIFO ! Le dernier élément entré est le premier sorti dans ton cas :
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Constante invalide
Posté par Obsidian . Évalué à 2.
Oui, c'est parce que j'ai un raccourci trop rapide, en effet.
Le principe demeure cela dit mais en fait, c'est déjà ce que tu fais à l'entrée. Tu décales à l'empilement et tu vas chercher la bonne position au dépilement. C'est effectivement l'un ou autre.
[^] # Re: Constante invalide
Posté par Etienne Bagnoud (site web personnel) . Évalué à 2.
Si je fais ainsi, c'est parce que l'empilement est fait durant une interruption, donc je fais le plus simple et court possible afin d'en sortir au plus vite.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Constante invalide
Posté par liberforce (site web personnel) . Évalué à 5. Dernière modification le 22 août 2012 à 16:52.
Si tu veux faire court en général:
au lieu de:
utilise plutôt:
Tu pourras désactiver les assertions dans un build en mode release. Perso je fais plutôt des fonctions is_empty que has_data, je pense que c'est plus répandu. Ah, et tu gagnes un tout petit peu sur le return, mais tu n'as certes plus tes initiales :)
[^] # Re: Constante invalide
Posté par Etienne Bagnoud (site web personnel) . Évalué à 3.
Pour les
assert
, je les utilises très peu dans les bibliothèques de fonctions : ces fonctions peuvent être utilisées dans du code dont tous les chemins n'ont pas été testés avant d'être en production et c'est souvent à ce moment là que le bug apparaît.Pour le
has_data
, perso je trouve plus joli :que
Mais c'est très personnel tout ça :)
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Constante invalide
Posté par liberforce (site web personnel) . Évalué à 2.
Ah mais je suis d'accord avec toi sur les assert, c'est juste que tu n'as pas dit que c'était pour une bibliothèque ;-).
Pour le has_data, je dirais que un popcorn_bag.has_data() est plus laid que popcorn_bag.is_empty(), même si effectivement, quand on écrit une application on a tendance à tester plus souvent la présence que l'absence de données (sauf dans les préconditions).
[^] # Re: Constante invalide
Posté par oinkoink_daotter . Évalué à 6.
C'est même encore mieux avec
:)
[^] # Re: Constante invalide
Posté par Patrick Lamaizière (site web personnel) . Évalué à 2.
Ama c'est justement là qu'ils sont utilent, là le code peut tourner bien après que la FIFO soit initialisée (même si elle est nulle). Ça devrait crasher dès le début. En plus ça spécifie le contrat.
Perso j'aime bien quand y'a des espaces dans le code, ça coûte pas chère et ça améliore la lisibilité (j'suis un vieux con à lunettes).
if (f->count > 0)
Pour info tu as sys/queue.h qui gère des listes tout en macros (mais pas de taille fixe).
http://fxr.watson.org/fxr/source/sys/queue.h
les pixels au peuple !
[^] # Lapin tout compris
Posté par MCMic (site web personnel) . Évalué à 1.
Il m'a pas mal perturbé de "& 0xFF".
Si j'ai compris, il s'agit en fait de ne garder que le dernier octet de data?
Si c'est bien ça, "& 0x000000FF" me semble plus lisible. (J'ai pu me gourer sur le nombre de 0)
[^] # Re: Lapin tout compris
Posté par barmic . Évalué à 10.
Tu viens d'expliquer pourquoi il ne l'a pas fait comme ça.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Lapin tout compris
Posté par reno . Évalué à 2.
Bah, le "& 0xFF" ne sert à rien puisque data est initialisé à 0 au départ et que c'est un unsigned int..
# compteur ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 10. Dernière modification le 21 août 2012 à 14:33.
C'est pas plus simple d'utiliser un tableau d'octet et un compteur de début et de fin ? Comme un buffer tournant ?
"La première sécurité est la liberté"
[^] # Re: compteur ?
Posté par Obsidian . Évalué à 4.
Si.
[^] # Re: compteur ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 1.
Si, mais ça fait une variable de plus, donc de la mémoire en moins.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: compteur ?
Posté par Obsidian . Évalué à 1.
C'est vrai, mais ça te permet en revanche de gérer une file d'une longueur arbitraire sans avoir à décaler tout son contenu. Avec 4 octets, la différence est subtile, avec 4096 elle devient beaucoup plus nette.
[^] # Re: compteur ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 2.
Oui, mais je veux une file pour quelques octets. Pour 4096 valeurs, j'utiliserais une version proche de celle présentée au début.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: compteur ?
Posté par Obsidian . Évalué à 2.
Oui mais justement, même pour quelques octets, c'est plus simple et plus efficace : en fait, la méthode des décalages telle que tu l'as écrite n'est intéressante qu'à partir du moment où ta file tient sur un seul entier (ou que les mots que tu empiles ne sont pas multiples de huit bits). Dès que tu dépasses 8 octets (si l'on considère le cas du long long), alors tu es obligé d'utiliser plusieurs variables consécutives.
De là, soit tu utilises une boucle et un pointeur, ce qui t'oblige à déclarer des variables supplémentaires, soit tu gères manuellement chacun de tes registres en contrôlant à chaque fois s'il est concerné en fonction de la valeur de « count ». Tu gagnes quatre octets de RAM mais tu perds 64 octets de ROM. Ce genre de chose est effectivement à prendre en compte dans le cas de micro-contrôleurs, mais pas sur PC. Pas seulement parce que la quantité de RAM disponible est considérable, mais surtout parce que c'est la même dans les deux cas.
[^] # Re: compteur ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 3.
Je pensais que la référence aux micro-contrôleurs en fin de journal permettrait de faire comprendre que la cible de ce code est des petits micro-contrôleurs avec quelques centaines d'octet de RAM.
Et si je veux un file pour 4 ou 8 octets, le cas où j'en ai 6000 ne m'intéresse pas. La vitesse de remplissage de la file est de l'ordre de 800 octets par secondes et je peux les traiter dix fois plus vite. Le seul cas où la pile est utilisée, c'est juste pour que le processeur dorme un peu plus et donc économise du courant (j'attend un taux de remplissage avant de commencer le traitement).
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: compteur ?
Posté par GaMa (site web personnel) . Évalué à 1.
Si tu veux jouer à ça :
Pardon aux familles …
Matthieu Gautier|irc:starmad
[^] # Re: compteur ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 4.
Non, mais j'ai mis, en fin de journal, des références aux micro-contrôleurs AVR ou PIC qui sont 8 bits et ont de quelques centaines d'octets à quelques kilo-octets de RAM disponible.
Donc des structures alignées sur 32 bits, voir 64 bits, … non.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: compteur ?
Posté par GaMa (site web personnel) . Évalué à 2.
Ouai, enfin à ce moment là, t'es en train de manipuler des entiers 32 bits avec un proc 8 bits. Tu gagnes peut-être en mémoire mais ça coute cher derrière au niveau proc. (Surtout que tu as l'air de vouloir faire ça rapidement, au regard d'un de tes autres commentaires)
Et puis ma première solution tient toujours :P
Matthieu Gautier|irc:starmad
[^] # Re: compteur ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 3.
Mais je privilégie l'espace mémoire à la vitesse. La vitesse, j'ai une bonne marge. La mémoire, peu de marge.
Mais je ne dis pas que ma solution est la solution. C'est une solution qui me semble élégante et fonctionnelle. Je peux me tromper lamentablement. C'est pourquoi je la présente, afin de partager ma réflexion et avoir des avis en retour (il y'a certainement des gens bien plus expérimentés que moi sur ce site).
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: compteur ?
Posté par GaMa (site web personnel) . Évalué à 2.
Bon c'est plus pour
le funla rigolade qu'autre chose, mais je l'ai fait avec un tableau circulaire.Je ne suis pas sur que ça sois plus performant …
Matthieu Gautier|irc:starmad
[^] # Re: compteur ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Je serais curieux de savoir si cela change quelques choses d'utiliser un tableau de taille 5 pour éviter d'avoir uns structure. Souvent les structures sont alignés en mémoire sur la taille du plus grand type C, qui peut être 16 bits ici. Ce n'est en général pas le cas des tableaux simples.
"La première sécurité est la liberté"
[^] # Re: compteur ?
Posté par windu.2b . Évalué à 5.
Y a beaucoup de bites, et peu de bits, dans ce commentaire…
[^] # Re: compteur ?
Posté par GaMa (site web personnel) . Évalué à -2.
Si il n'y avait que ça…
Mais bon, je me suis déjà excusé par avance.
Matthieu Gautier|irc:starmad
[^] # Re: compteur ?
Posté par barmic . Évalué à 7.
C'est cool les excuses, c'est comme les démentis de ministres ou les condamnations de chefs d'État. Ça coûte rien, ça fais joli à la télé et personne te demande d'être sincère.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: compteur ?
Posté par GaMa (site web personnel) . Évalué à -2.
A ouai, en fait vous avez aucun humour dès que c'est un peu sexuel, c'est ça ?
(Et qu'on ne me parle pas de sexisme, je ne vois pas pourquoi les filles devraient être plus choquées que les garçon, ou inversement)
La prochaine fois, je ne m'excuserai pas. Na!
Matthieu Gautier|irc:starmad
[^] # Re: compteur ?
Posté par barmic . Évalué à 3.
En fait tu n'a aucun humour dès que ça parle à peine de sexe ?
L'ironie était trop subtile ? Je présumais que l'allusion aux politiques aurait suffit à te faire voir l'humour.
Par contre je ne m'excuse pas de la situation, je préfère rester sincère (et là ce n'est pas ironique).
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: compteur ?
Posté par Obsidian . Évalué à 5.
Un journal qui parle de langage C, qui tente de résoudre un cas de figure technique et qui finit en troll politico-sexiste dès le cinquième niveau d'imbrication : pas de doute, on est bien sur DLFP. Tout va bien. :-)
[^] # Re: compteur ?
Posté par fearan . Évalué à 2.
en même temps ça parle de pipe…
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: compteur ?
Posté par UnixJunkie . Évalué à 1.
Petite implémentation sans compteur, pour le fun:
[^] # Re: compteur ?
Posté par reno . Évalué à 2. Dernière modification le 22 août 2012 à 16:51.
Tes char tiennent sur 7bits, les originaux sur 8bits sinon c'est amusant comme idée: maximiser la performance du push, au détriment d'avoir un pop/read lent.
Autre méthode avec le même stockage qu'à l'origine:
Après il y a des fonctions qui donne le numéro du bit de poids fort qui peuvent être plus performante mais moins portable.
[^] # Re: compteur ?
Posté par 2PetitsVerres . Évalué à 2.
Et la taille du code ? (bon évidemment s'il reste en ROM il n'est pas en RAM, mais généralement le code est en RAM. Donc faut bien vérifier lequel prend vraiment moins de place…)
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
[^] # Re: compteur ?
Posté par Narishma Jahar . Évalué à 1.
La plupart des micro-controlleurs (en tout cas ceux que j'ai utilisé) exécutent le code directement à partir de la ROM, sans le copier en RAM.
# Merci
Posté par rakoo (site web personnel) . Évalué à 10.
Je ne pratique pas le C parce que les soucis de gestion bas niveau ne m'avaient pas l'air intéressants. Mais avec ce journal et le dernier, agrémentés de petits commentaires qui font vivre le code et nous donnent des explications sur le pourquoi, ça donne envie. J'aime beaucoup l'approche linéaire qui suit le raisonnement qu'aurait un développeur.
J'ai hâte de lire la suite !
En un mot : Merci !
[^] # Re: Merci
Posté par Etienne Bagnoud (site web personnel) . Évalué à 4.
:) ça fait plaisir ce genre de commentaires. Merci.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Merci
Posté par reno . Évalué à 1.
Sur de petit exemples comme ça, c'est amusant les optimisations de bas niveau, c'est quand tu essaye de faire un "gros" programme que tu vois rapidement l'intérêt des langage de haut niveau comme Python/OCaml..
# question conne
Posté par Guillaume Denry (site web personnel) . Évalué à 3.
A quoi te sert le return à la fin de sf_init ? C'est ptête un oubli de ta part ou bien une subtilité qui m'aurait échappé, c'est pour ça que je pose la question.
[^] # Re: question conne
Posté par Etienne Bagnoud (site web personnel) . Évalué à 6.
Je trouve joli les
return;
. C'est la seule explication."It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: question conne
Posté par Guillaume Denry (site web personnel) . Évalué à 10.
C'est vrai que maintenant que tu le dis, plus je le regarde et plus les larmes me montent aux yeux.
[^] # Re: question conne
Posté par Gabin . Évalué à -3.
+42 pour m'avoir déclenché un fou-rire.
# Gestion des paramètres
Posté par barmic . Évalué à 3. Dernière modification le 21 août 2012 à 15:47.
Dans toutes tes fonctions tu gère les paramètres
NULL
comme ça :Je comprend bien le coté esthétique, mais n'est-il pas plus performant (si on considère que l'utilisateur va plus souvent t'envoyer un pointeur valide qu'un NULL) d'écrire :
Si je ne me trompe pas ça diminue les erreurs de prefetch d'instructions par la CPU (je crois savoir que c'est important sur des CPU avec un pipeline long comme les P4, je ne sais pas si c'est valable sur ton micro-controlleur.
PS : à la réflexion la condition est un peu plus lourde donc peut être que c'est pas si bien que ça.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Gestion des paramètres
Posté par Etienne Bagnoud (site web personnel) . Évalué à 3.
Tu soulèves un point pertinent. Je n'ai rien vu sur ce sujet, mais comme il y a une instruction
Compare, Skip if Equal
, ça me semble logique de le faire comme je le fais. Maintenant je n'ai pas encore regarder plus en détail que ça."It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Gestion des paramètres
Posté par Zylabon . Évalué à 1.
Je suis aussi étonné de cette gestion des paramètres nulls, je ne comprend pas quel sens aurait l'initialisation réussie de rien du tout.
Ça me semble risquer le fait que l'on puisse faire tourner ce code super longtemps avant de se rendre compte qu'il n'y a tout simplement pas de file et que les fonctions faisaient poliment semblant de travailler dessus « Ne le contrarions pas, dieu sait ce qu'il nous arriverait sinon ».
Please do not feed the trolls
[^] # Re: Gestion des paramètres
Posté par Cédric Chevalier (site web personnel) . Évalué à 2.
Beaucoup de processeurs (dont le P4) ont une bonne prédiction de branchement. De plus on peut espérer que si sur l'architecture cible la deuxième écriture est beaucoup plus performante que la première le compilateur fasse l'optimisation tout seul. De manière générale, si on peut se permettre de tester partout, il parait plus approprié d'écrire le code le plus lisible possible.
[^] # Re: Gestion des paramètres
Posté par liberforce (site web personnel) . Évalué à 3.
En cas de doute tu peux optimiser cela. La GLib utilise les macros G_LIKELY/G_UNLIKELY comme front-end aux directives gcc idoines.
Du coup, un:
n'est pas moins clair ni performant, juste un poil plus lourd à écrire. Reste plus qu'à tester la version avec et sans pour son architecture, pour savoir si cela apporte quelque chose ou si la prédiction de branches de gcc est suffisante.
[^] # Re: Gestion des paramètres
Posté par barmic . Évalué à 1.
Quelle heuristique ils utilisent ?
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Gestion des paramètres
Posté par Anthony Jaguenaud . Évalué à 3.
Ils ont une table interne au processeur. Quand tu passes sur un choix, il vire l’entrée la plus ancienne et ajoute que à telle adresse on a sauté ou pas. Au passage suivant il recommence. Au bout de quelques passages, si le saut est plus courant, le proc va suposé que tu va « jumpé » (le saut) est donc remplir le pipe avec ce qui suit le saut. Ça évite le flush du pipe en cas de mauvais branchement.
J’avais fait des tests sur PowerPC en 2004 pour mon boulot sur une petite fonction.
1er passage 2μs (2000ns)
2ième passage 1800ns. (cache instruction rempli)
…
18ième passage 1800ns.
19ième passage 950ns.
…
De 2 à 18 le temps varié avec un écart type de 50ns. Au 19ième passage, je gagnais 1μs. Il faut voir que ceci se met en place que en cas de boucle, et si un autre processus ne prend pas la main pour exploser tous les points de passage noté.
Ce test remonte à il y a quelques temps. Je ne sais pas comment gère les CPUs multi-cœur. La table est-elle commune ? ou lié à un cœur ? Dans ce cas, l’OS a intérêt à remettre un même thread sur le même cœur.
[^] # Re: Gestion des paramètres
Posté par Vador Dark (site web personnel) . Évalué à 3.
Le problème d'un tel mécanisme sur le type de cible de l'auteur, c'est que si son temps de traitement est trop lent avant que le proco n'ait optimisé la boucle, le buffer explose. Et si le traitement "non optimisé" est suffisamment rapide, alors l'optimisation ne sert à rien.
Les applications de ce type sont généralement temps réelles. Il faut traiter les données à mesure qu'elles se présentent au micro-contrôleur : impossible de les traiter plus rapidement, interdit de les traiter plus lentement.
(En outre, un proco 8 bits à peu de chance de posséder un tel mécanismes de prédictions).
[^] # Re: Gestion des paramètres
Posté par Nicolas Boulay (site web personnel) . Évalué à 3.
Il existe plusieurs niveau de complexité.
Les instructions de saut typique contiennent l'adresse de saut. Il faut savoir si le saut est effectué ou pas avant la fin de l’exécution de "quelques instructions" dans le pipeline.
Le niveau le plus basique est : "forward not taken, backward taken". En gros, si l'adresse est en avant du PC, le saut n'est pas pris (cas d'un if qui est vrai), si le saut est en arrière, il est pris (cas d'une boucle).
Dans les faits, cette prédiction n'est pas si mauvaise que ça.
Le niveau suivant utilise une machine d'état à 4 états : strong taken - taken - not taken - strongly not taken. Le saut effectué ou pas fait changer d'état cette machine d'état. Il existe des cpu qui ont une seul de ces machines, pour aller plus loin que la prédiction statique. Les cpu moderne disposent de ces 2 bits d'information pour quelques centaines d'adresses d'instruction de saut.
Seul les cpus de la génération du core 2 et suivant possèdent une gestion des sauts indirects, avec sauvegarde de l'adresse de saut dans le buffer (comme les tableaux de fonction ou les vtable).
"La première sécurité est la liberté"
[^] # Re: Gestion des paramètres
Posté par barmic . Évalué à 2.
Merci pour les explications.
Ça signifie bien que c'est le return qui est chargé dans le cas présent, c'est ça ?
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Gestion des paramètres
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Dans ton code objet, le fetcher du cpu, le bloc qui va chercher les instructions a executer va tomber sur un
JUMP 0X012345678
Cette instruction peut être conditionnel, or la condition n'est pas calculer. Il doit choisir si il va chercher l'adresse PC+4 comme d'habitude (sur un risc 32 bits) ou 0x012345678.
Savoir si la clause du if qui est exécuté dépend de la forme du code assembleur choisi par le compilateur. J'aurais tendance à dire que dans un if qui a 2 clause, la clause vrai sera privilégié, mais si il n'y a qu'une clause, elle sera sauté.
"La première sécurité est la liberté"
# static ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Est-ce que ce genre de code est mis dans un .h ou dans son .c à part ?
Si la bibliothèque est souvent utilisé, du code "static" (ou static inline) peut être très compact, si mis dans le .h.
"La première sécurité est la liberté"
[^] # Re: static ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 2.
Je n'ai pas encore décidé ça. Des macros pourraient être très bien. En fait, depuis quelques jours, je me remet sur des micro-contrôleurs et je fais la liste de ce que j'aurais besoin comme "outils". Après je vais pondre le code, sans optimisation, et ensuite j'optimise.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: static ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
les fonctions static font la même chose que les macros mais en plus propre (si le compilateur n'est pas moisi).
"La première sécurité est la liberté"
[^] # Re: static ?
Posté par liberforce (site web personnel) . Évalué à 2.
Apparemment il y a un léger overhead pour les fonctions inline, ce n'es pas strictement identique. Mais ça te donne de la vérification statique de type, et je trouve ça largement acceptable comme contrepartie.
[^] # Re: static ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
L'overhead des fonctions inline est en général dû à l'absence du mot clef "static". Sans ce mot, le symbol doit être visible de l'extérieur du .o et ainsi en plus des copies de la fonction en ligne, une fonction "normal" existe.
Gcc demande juste "static", "static inline" n'est plus nécessaire.
"La première sécurité est la liberté"
# API perfectible
Posté par reno . Évalué à 2.
A mon avis le push pourrait indiquer s'il y a eu overflow ou pas en retournant une valeur.
Tu utilise quel version du C?
Si c'est le C99, un bool est plus lisible que des valeurs "magiques" codés dans un char pour le code retour de sf_pop, après le bool est probablement codé sur un entier que sur un char, mais bon..
[^] # Re: API perfectible
Posté par Etienne Bagnoud (site web personnel) . Évalué à 1.
Oui, ça pourrait être utile.
C99 ou C89, quelle importance. La seul chose importante, dans ce cas, c'est d'avoir une valeur différente de 0 pour faire un
while(...)
. Dans tous les cas, je préfère me dire que je code en C89 et faire ainsi."It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: API perfectible
Posté par reno . Évalué à 2.
Hum, la lisibilité c'est important, mais bon pas tant que ça sur du code aussi court..
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.