Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
Optimiser des multiplications sur PIC16
- Claudius
Passionné- Messages : 260
- Âge : 69
- Enregistré en : septembre 2015
- Localisation : ELANCOURT (78 - YVELINES)
- Contact :
Merci satinas,
Cela confirme l'expérience que j'ai des compilateurs et de leurs niveaux d'optimisation (compromis entre le temps d'exécution du code généré et de la taille de celui-ci, sans parler des bugs que l'optimiseur apporte parfois en voulant "bien faire")
Cela confirme l'expérience que j'ai des compilateurs et de leurs niveaux d'optimisation (compromis entre le temps d'exécution du code généré et de la taille de celui-ci, sans parler des bugs que l'optimiseur apporte parfois en voulant "bien faire")
Enregistreur de traces GPS & Boussole GPS parlante (PIC & Arduino)
Optimiser des multiplications sur PIC16
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour
en mikroC
// en unsigned int 16 ..tres peu d'ecart par rapport à l'usage de x seul
// en unsigned long 32 bits
en mikroC
// en unsigned int 16 ..tres peu d'ecart par rapport à l'usage de x seul
Code : Tout sélectionner
x = 5;
y = 3;
z = 300; // ... MikroC 7.61
x <<= 10; // 95
x /= y ;// 351
x *= z ;// 190
x >>= 10;// 90
// en unsigned long 32 bits
Code : Tout sélectionner
x1 = 5;
y1 = 3;
z1 = 300; // .. mikroC
x1 <<= 10; // 123
x1 /= y1 ;// 1028
x1 *= z1 ;// 611
x1 >>= 10;// 114
Optimiser des multiplications sur PIC16
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
Re. J'ai eu des trucs à faire ^^
Intéressant qu'il y a de tels différences ! En tout cas mes décalages ont l'air d'être clairement plus rapides que des multiplications/divisions par 1000, 10000 etc :)
Pour un float il faut faire des calculs pour les chiffres significatifs mais aussi pour l'exposant. Du coup le long me semble meilleur ?
Pourquoi ça ne prend pas tout simplement que la partie utile ?
Tout à fait. Mais je pense que je vais l'être aussi sans ^^
Sinon ce site m'a l'air intéressant mais j'ai du mal à trouver.
J'ai regardé pour des PICs 16bit mais ça consomme trop :/
J'ai testé et j'ai cette erreur :
Par contre pour la plupart des variables j'ai besoin de long pour ne pas perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs. D'ailleurs des variables de 64bits seraient même plus pratiques pour certains calculs.
Intéressant qu'il y a de tels différences ! En tout cas mes décalages ont l'air d'être clairement plus rapides que des multiplications/divisions par 1000, 10000 etc :)
et une utilisation de long 32 bits pour eviter les floats ?
Pour un float il faut faire des calculs pour les chiffres significatifs mais aussi pour l'exposant. Du coup le long me semble meilleur ?
des qu'on utilise une multiplication ou division, on embarque dans le code toute la librairie Maths..
qui pese pas mal en taille.
Pourquoi ça ne prend pas tout simplement que la partie utile ?
^^Je lui propose pas, il risque d'être là après le confinement
Tout à fait. Mais je pense que je vais l'être aussi sans ^^
Sinon ce site m'a l'air intéressant mais j'ai du mal à trouver.
Les pic 16 bits font des opérations int 16*16->32 en 1 cycle et 32/16->16 en 18 cycles.
Avec les dsPic on passe à 6 cycles, et on a en plus le fractionnaire à virgule fixe 16 bits à la même vitesse.
J'ai regardé pour des PICs 16bit mais ça consomme trop :/
Pour les entiers xc8 24 bits unsigned short long, il faut passer en C90 dans les options de compilation.
J'ai testé et j'ai cette erreur :
Code : Tout sélectionner
main.c:53:16: error: cannot combine with previous 'short' declaration specifier
unsigned short long a ;
Par contre pour la plupart des variables j'ai besoin de long pour ne pas perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs. D'ailleurs des variables de 64bits seraient même plus pratiques pour certains calculs.
Optimiser des multiplications sur PIC16
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
à ma connaissance, il n'y a pas de VRAI double, avec MicroC (MCU 8 bits)
un double (flottant) => 64 bits
meme si on declare un float en double ..ça reste un simple float sur 32 bits .. donc adieu la haute precision de calculs flottants
(voir les discussions au sujet des calculs de distance avec longitude et latitude)
concernant les entiers, limite à 32 bits seulement en non signés ( unsigned long) ou +-31 bits en signés.(signed long)
si on connait par avance le domaine de variation des variables, ça peut bien dépanner .
il suffit d'utiliser un seul element d'une librairie (C_STDlib par exemple) pour activer l'ensemble
à noter au passage que d'autres librairies sont tres voraces en taille
ex: PPS_Mapping , rien que pour activer l'UART sur les pins RC6 et RC7 ................. 1584 bytes , rien que pour utiliser l' UART !!!
ou _doprntf , si usage de sprintf ..8968 bytesUART
sinon la plupart des operations de calculs (x, div, ...) se font dans des elements de la lib C_Stdlib
le graphique ( Statistiques) ci dessous le montre bien
(pas de soucis avec ce PIC18F27K42 qui a 128Ko de flash !)
les seuls calculs utilisés dans le programme de test
nota : je plussoie ici à l'usage de l'asm , si on a un PIC avec peu de FLASH ROM !
Superphénix a écrit :..
Par contre pour la plupart des variables j'ai besoin de long pour ne pas perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs. D'ailleurs des variables de 64bits seraient même plus pratiques pour certains calculs.
à ma connaissance, il n'y a pas de VRAI double, avec MicroC (MCU 8 bits)
un double (flottant) => 64 bits
meme si on declare un float en double ..ça reste un simple float sur 32 bits .. donc adieu la haute precision de calculs flottants
(voir les discussions au sujet des calculs de distance avec longitude et latitude)
concernant les entiers, limite à 32 bits seulement en non signés ( unsigned long) ou +-31 bits en signés.(signed long)
si on connait par avance le domaine de variation des variables, ça peut bien dépanner .
il suffit d'utiliser un seul element d'une librairie (C_STDlib par exemple) pour activer l'ensemble
à noter au passage que d'autres librairies sont tres voraces en taille
ex: PPS_Mapping , rien que pour activer l'UART sur les pins RC6 et RC7 ................. 1584 bytes , rien que pour utiliser l' UART !!!
ou _doprntf , si usage de sprintf ..8968 bytesUART
Code : Tout sélectionner
clk = Clock_kHz();
sprintf(txt," Clock initiale in Khz = %05u \r\n",clk);
UART1_Write_Text(txt);
sinon la plupart des operations de calculs (x, div, ...) se font dans des elements de la lib C_Stdlib
le graphique ( Statistiques) ci dessous le montre bien
(pas de soucis avec ce PIC18F27K42 qui a 128Ko de flash !)
les seuls calculs utilisés dans le programme de test
Code : Tout sélectionner
// unsigned long
L1=65538;
L2=L1*10;
F1=10.0 ;
F2=F1*0.56;
nota : je plussoie ici à l'usage de l'asm , si on a un PIC avec peu de FLASH ROM !
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Modifié en dernier par paulfjujo le ven. 8 mai 2020 13:08, modifié 1 fois.
Optimiser des multiplications sur PIC16
- Claudius
Passionné- Messages : 260
- Âge : 69
- Enregistré en : septembre 2015
- Localisation : ELANCOURT (78 - YVELINES)
- Contact :
Bonjour Superphénix et tout le forum,
Quelle est donc, si je puis me permette, cette absolue nécessité de ne pas "perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs" ?
S'agissant de "... des variables de 64bits seraient même plus pratiques pour certains calculs", alors là cela m'intéresse au plus haut point ?!..
Lire er relire les limites des codages des float 32 bits et des double 64 bits
Merci par avance pour ma culture ;-)
Superphénix a écrit :
..
Par contre pour la plupart des variables j'ai besoin de long pour ne pas perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs. D'ailleurs des variables de 64bits seraient même plus pratiques pour certains calculs.
Quelle est donc, si je puis me permette, cette absolue nécessité de ne pas "perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs" ?
S'agissant de "... des variables de 64bits seraient même plus pratiques pour certains calculs", alors là cela m'intéresse au plus haut point ?!..
Lire er relire les limites des codages des float 32 bits et des double 64 bits
Merci par avance pour ma culture ;-)
Enregistreur de traces GPS & Boussole GPS parlante (PIC & Arduino)
Optimiser des multiplications sur PIC16
Bonjour,
C'est pas moi qui l'ai dit.......
A+
paulfjujo a écrit :Source du message nota : je plussoie ici à l'usage de l'asm , si on a un PIC avec peu de FLASH ROM !
C'est pas moi qui l'ai dit.......
A+
Optimiser des multiplications sur PIC16
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
Quelle est donc, si je puis me permette, cette absolue nécessité de ne pas "perdre en chiffres significatifs et à la fois pouvoir traiter des grandes valeurs" ?
S'agissant de "... des variables de 64bits seraient même plus pratiques pour certains calculs", alors là cela m'intéresse au plus haut point ?!..
J'ai une variable dans mon programme qui contiens un nombre pouvant varier entre 0 et 1 000 000. Ce nombre à un moment je dois le multiplier par un nombre à virgule parmi une liste stocké dans un tableau. Pour optimiser les temps de calculs, je ne stocke pas des nombres à virgules en float mais des nombres entiers en unsigned long (ou unsigned short long si je finis par y arriver) et je commence par faire un décalage avant de faire une division. Exemple :
Au lieux de faire : 1 000 000 x 3.2568 = 3 256 800
Je fais : (1 000 000 << 16) / DIVISEUR[n] = 3 256 770 // Avec DIVISEUR[n] = (1/3.2568)*2^16 = 20123
Le problème c'est que si je fait ça alors 1 000 000<<16 = 65 536 000 000, ce qui dépasse largement un unsigned long de 32bits.
à ma connaissance, il n'y a pas de VRAI double, avec MicroC (MCU 8 bits)
Un entier en 48 bits m’irait aussi. Genre un unsigned short long short
Je réfléchis à comment diviser le calcul en 2 étapes avec 2 variables unsigned long...
Optimiser des multiplications sur PIC16
Chez moi le type "unsigned short long" nécessite de cocher C90.
Le compilateur préconise le type "__uint24", il passe avec C90 ou C99 coché, ce warning de compilation en parle
C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
Tu peux introduire des calibres en faisant varier la valeur du prescaler timer (1/2/4/8), et celui du module CCP (1/4/16).
A quoi sert ce montage ?
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Optimiser des multiplications sur PIC16
- Claudius
Passionné- Messages : 260
- Âge : 69
- Enregistré en : septembre 2015
- Localisation : ELANCOURT (78 - YVELINES)
- Contact :
Bonjour,
Merci Superphénix pour les précisions (c'est le cas de le dire ;-)
Sinon, jette un coup d’œil sur:
- Les Q-Nombres
- Nombre à virgule fixe
car le Q-Format / Convertisseur a été inventé pour cela et devrait répondre à ta demande.
De plus, l'implémentation des 4 opérations dans ce format est relativement simple et légère + le codage des 2 conversions "Q-Format" <-> "Notation naturelle" en début et fin de calcul
A suivre...
Merci Superphénix pour les précisions (c'est le cas de le dire ;-)
Sinon, jette un coup d’œil sur:
- Les Q-Nombres
- Nombre à virgule fixe
car le Q-Format / Convertisseur a été inventé pour cela et devrait répondre à ta demande.
De plus, l'implémentation des 4 opérations dans ce format est relativement simple et légère + le codage des 2 conversions "Q-Format" <-> "Notation naturelle" en début et fin de calcul
A suivre...
Enregistreur de traces GPS & Boussole GPS parlante (PIC & Arduino)
Optimiser des multiplications sur PIC16
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
car le Q-Format / Convertisseur a été inventé pour cela et devrait répondre à ta demande.
Fouu! J'étais fière d'avoir inventé un truc, et là vous me dites que ça existe déjà et que ça porte même un nom.
Au moins je suis rassuré de ne pas faire un truc bizarre qui ne se fait pas pour x raisons... ^^
Par contre dans l'exemple du lien ils utilisent toujours une variable intermédiaire qui est plus grande que les variables des opérandes (int32_t au lieux de int16_t). Ce qui me remène au même problème: il me faut une variable avec plus de 32bits.
Par contre je viens de résoudre le problème en faisant en deux étapes et avec des multiplications.
Exemple avec toujours les mêmes valeurs :
Résultat = (1000000>>16)*213438 + (((1000000 & 0x0000FFFF)*213438)>>16) = 3256805
Tu peux introduire des calibres en faisant varier la valeur du prescaler timer (1/2/4/8), et celui du module CCP (1/4/16).
A quoi sert ce montage ?
Non cette valeur n'a rien avoir avec le timer dont on a parlé sur un autre poste. Là c'est pour mesurer une distance et avant de l'afficher sur l'écran je la convertis au choix en m, km, mils, etc, d'où la liste de valeurs par lesquels je voulais diviser à la fin.
Chez moi le type "unsigned short long" nécessite de cocher C90.
C'est ce que j'avais fait. Par contre là j'ai relancé MPLAB et ça a changé quelque chose. Maintenant j'ai ces warnings et erreurs :
Code : Tout sélectionner
main.c:102:26: warning: (373) implicit signed to unsigned conversion
main.c:106:45: warning: (373) implicit signed to unsigned conversion
main.c:107:24: warning: (373) implicit signed to unsigned conversion
main.c:112:24: warning: (373) implicit signed to unsigned conversion
main.c:113:19: warning: (373) implicit signed to unsigned conversion
main.c:138:58: warning: (373) implicit signed to unsigned conversion
main.c:139:63: warning: (373) implicit signed to unsigned conversion
main.c:140:63: warning: (373) implicit signed to unsigned conversion
main.c:141:63: warning: (373) implicit signed to unsigned conversion
main.c:310:50: warning: (373) implicit signed to unsigned conversion
main.c:322:59: warning: (373) implicit signed to unsigned conversion
main.c:323:55: warning: (373) implicit signed to unsigned conversion
main.c:370:19: warning: (373) implicit signed to unsigned conversion
main.c:370:36: warning: (373) implicit signed to unsigned conversion
main.c:370:74: warning: (373) implicit signed to unsigned conversion
main.c:409:19: warning: (373) implicit signed to unsigned conversion
main.c:410:19: warning: (373) implicit signed to unsigned conversion
main.c:411:19: warning: (373) implicit signed to unsigned conversion
main.c:412:19: warning: (373) implicit signed to unsigned conversion
main.c:463:35: warning: (373) implicit signed to unsigned conversion
main.c:463:46: warning: (373) implicit signed to unsigned conversion
main.c:464:37: warning: (373) implicit signed to unsigned conversion
main.c:475:31: warning: (373) implicit signed to unsigned conversion
main.c:475:40: warning: (373) implicit signed to unsigned conversion
main.c:475:44: warning: (373) implicit signed to unsigned conversion
main.c:479:33: warning: (373) implicit signed to unsigned conversion
main.c:479:42: warning: (373) implicit signed to unsigned conversion
main.c:479:46: warning: (373) implicit signed to unsigned conversion
main.c:486:54: warning: (373) implicit signed to unsigned conversion
main.c:493:40: warning: (373) implicit signed to unsigned conversion
main.c:493:51: warning: (373) implicit signed to unsigned conversion
main.c:496:27: error: (269) inconsistent type
main.c:497:1: error: (984) type redeclared
main.c:497:1: error: (1098) conflicting declarations for variable "POINTS" (main.c:496)
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 32 invités