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 ---
Forum général sur le langage C !

Modérateur : Jérémy

Optimiser des multiplications sur PIC16
Claudius
Avatar de l’utilisateur
Passioné
Passioné
Messages : 260
Âge : 69
Enregistré en : septembre 2015
Localisation : ELANCOURT (78 - YVELINES)
Contact :

#11 Message par Claudius » mar. 5 mai 2020 15:52

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")

Optimiser des multiplications sur PIC16
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#12 Message par paulfjujo » mar. 5 mai 2020 17:42

bonjour

en mikroC
// en unsigned int 16 ..tres peu d'ecart par rapport à l'usage de x seul

Code : Tout sélectionner

= 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
Aide toi, le ciel ou FantasPic t'aidera

Optimiser des multiplications sur PIC16
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#13 Message par Superphénix » ven. 8 mai 2020 01:23

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 :)

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
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#14 Message par paulfjujo » ven. 8 mai 2020 10:21

bonjour,

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 , :furieux: 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



Stat_functions.jpg



:sifflotte: 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.
Aide toi, le ciel ou FantasPic t'aidera

Optimiser des multiplications sur PIC16
Claudius
Avatar de l’utilisateur
Passioné
Passioné
Messages : 260
Âge : 69
Enregistré en : septembre 2015
Localisation : ELANCOURT (78 - YVELINES)
Contact :

#15 Message par Claudius » ven. 8 mai 2020 11:17

Bonjour Superphénix et tout le forum,
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 ;-)

Optimiser des multiplications sur PIC16
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#16 Message par Temps-x » ven. 8 mai 2020 16:16

Bonjour,

:+1:
paulfjujo a écrit :Source du message :sifflotte: nota : je plussoie ici à l'usage de l'asm , si on a un PIC avec peu de FLASH ROM !


:-D C'est pas moi qui l'ai dit.......

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Optimiser des multiplications sur PIC16
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#17 Message par Superphénix » dim. 10 mai 2020 02:05

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 :razz:


Je réfléchis à comment diviser le calcul en 2 étapes avec 2 variables unsigned long...

Optimiser des multiplications sur PIC16
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#18 Message par satinas » dim. 10 mai 2020 09:32

xc8_C90_C99_uint24.png
Bonjour

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
Avatar de l’utilisateur
Passioné
Passioné
Messages : 260
Âge : 69
Enregistré en : septembre 2015
Localisation : ELANCOURT (78 - YVELINES)
Contact :

#19 Message par Claudius » dim. 10 mai 2020 09:54

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...

Optimiser des multiplications sur PIC16
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#20 Message par Superphénix » lun. 11 mai 2020 03:25

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. :furieux: :-D
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.

idea ! 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)

:?: :?: :?:


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 49 invités