Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 09/09/2011, à 19:48

temps

[résolu] Comment limiter une opération en langage C

bonjour,
J'utilise la class math en langage C pour effectuer des opérations arithmétiques.
Certaines de mes opérations utilisent des doubles qui varient.
Quand l'opération est x = 0.5 * 2;
c'est rapide mais quand l'opération est x = 1 / 3 l'opération est très lente car elle va chercher des informations inutiles, j'entends en ces termes une précision qui ne me sert à rien, un réponse à trois chiffre après la virgule me suffit.
Est-ce que quelqu'un sait comment limiter le calcul effectué, un peu comme le fait open office dans son tableur ?
le but étant d'avoir une application rapide ?
Cordialement

Dernière modification par temps (Le 11/09/2011, à 00:19)


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#2 Le 09/09/2011, à 20:11

mjdon

Re : [résolu] Comment limiter une opération en langage C

C'est juste qu'il n'existe pas de moyen simple d'effectuer une division avec un processeur. Tu peux regarder les routines en assembleur nécessaire pour effectuer une multiplication et une division. Il n'y a pas photo. Si tu veux moins de précision, utilise des variables plus courtes: par exemple un float à la place d'un double.

edit: Est ce que tu as un problème précis à proposer où le temps de calcul n'est pas acceptable? En général il y à beaucoup de choses à faire pour optimiser un code avant de s'inquiéter du poids d'une division. Par exemple, faire une division une fois et stocker le résultat avant de l'utiliser dans une boucle.

Dernière modification par mjdon (Le 09/09/2011, à 20:20)

Hors ligne

#3 Le 09/09/2011, à 21:09

temps

Re : [résolu] Comment limiter une opération en langage C

Merci pour la réponse. En fait c'est une opération que j'effectue des milliers de fois par seconde et j'utilise la fonction exp d'ou le double qui est au minimum imposé par cette fonction. La présentation d'une division n'était la que pour indiquer la saturation d'un double, je ne fais pas de division.
Actuellement j'utilise des tableaux qui donnent pour le temps de réaction une réponse largement supérieur au flux de sortie des données nécessaire, mais voila la solution des tableaux introduit une forme d'escalier qui selon est gênante. Cela ne se vois pas mais ressort dans une analyse plus générale.
Développer des sous tableaux me demanderai des jours de travail, avant d'envisager cette solution, je me demande s'il n'y a pas un solution plus simple pour écrire tout simplement ma fonction exp première mais limité après la virgule, car ma fonction est une valeur proportionnelle et travaille entre presque zéro et presque 1.

J'ai trouvé après quelques recherches sur la toile a http://www.cplusplus.com/reference/clibrary/cmath/exp/  l'expression       float exp (       float x );
Je vais voir et je donne la réponse, c'est certain même si j'ai bien plus que 3 chiffre après la virgule, cela devrait améliorer par rapport à un double.
pourtant toutes les docs sur exp que j'avais vu avant avaient données que double

Dernière modification par temps (Le 09/09/2011, à 21:40)


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#4 Le 09/09/2011, à 22:26

mjdon

Re : [résolu] Comment limiter une opération en langage C

Si tu as plusieurs coeurs et que chaque instance de ta boucle sont indépendantes, tu peux essayer de parallélisable avec openmp. Sinon tu peux essayer de bricoler les options de compilation, par exemple essayer -O2 ou -O3 avec gcc.

Hors ligne

#5 Le 09/09/2011, à 23:13

temps

Re : [résolu] Comment limiter une opération en langage C

Je le sens plus dans le bricolage d'une fonction exp perso ou encore dans le développement de tableaux que dans une astuce limité.
En d'autre mots l'utilisation est créée pour être diffusée gratuitement dans le monde linux, donc assez portable sur les différents P.C.
Peut être le plus simple serait d'aller dans la class math, supprimer tout ce qui est inutile et ne garder que la partie customisé qui est utile à mon code ?

Dernière modification par temps (Le 10/09/2011, à 15:50)


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#6 Le 10/09/2011, à 21:42

temps

Re : [résolu] Comment limiter une opération en langage C

En fouillant dans math.h , j'ai pas trouvé ou était traité la fonction exp, aussi j'ai fais quelques recherches sur la toile pour y trouver une dizaine de techniques différentes plus ou moins intéressantes.
Dans le lot celle qui m'a le plus attirée est celle là
exp(x) = 1 + x + (x*x)/2!+(x*x*x)/3!
ou encore
1 + x + (x*x)*0.5+(x*x*x)*0./166667
soit quatre aditions et si la précision ne suffit pas il me suffit d'ajouter une adition en perdant en vitesse d'exécution.
Qu'en pensez-vous ?

Dernière modification par temps (Le 10/09/2011, à 21:45)


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#7 Le 11/09/2011, à 00:18

temps

Re : [résolu] Comment limiter une opération en langage C

Je poste en résolu, le code fonctionne

    float jj;
    jj = (-1) * (nbdepoints * 0.037);

    jo = (float)(nbdepoints * (1 - ( 1 + jj + (jj*jj*0.5) + (jj*jj*jj*0.1667)+ (jj*jj*jj*jj*0.04167)+ (jj*jj*jj*jj*jj*0.008333))));

Toutes fois moi qui travaille entre presque 0 et presque 1, je suis obligé de resté sur des composantes impaires de jj sinon nous obtenons une erreur de segmentation, pas à la compilation, mais à l'appel de la fonction.


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#8 Le 11/09/2011, à 08:20

mjdon

Re : [résolu] Comment limiter une opération en langage C

Bien joué. Pour l'erreur de segmentation, je ne pense pas que ce soit du à la fonction en elle même mais à la façon dont tu accède à ton tableau au moment ou tu l'appelle. Je suppose que tu va très bien te débrouiller pour débugger ça. Juste par curiosité, tu as gagné combien de temps en interpolant ta fonction?

Hors ligne

#9 Le 11/09/2011, à 23:45

temps

Re : [résolu] Comment limiter une opération en langage C

mjdon a écrit :

Bien joué. Pour l'erreur de segmentation, je ne pense pas que ce soit du à la fonction en elle même mais à la façon dont tu accède à ton tableau au moment ou tu l'appelle. Je suppose que tu va très bien te débrouiller pour débugger ça. Juste par curiosité, tu as gagné combien de temps en interpolant ta fonction?

En fait c'est pas encore au point qu'en j'ai fait d'autres tests, mais la voix est ouverte, vers ce type de solution. Le temps est divisé par des millions, ce qui me permet de créer un format wav plus rapidement que ce qu'il est lu. En d'autres mots le wav lit 44100 x 2 données de deux octets par seconde (176 400 octets/s), et donc le fait d'utiliser une des opérations mieux écrites que ce qui se trouve dans math.h permets d'avoir une création de données plus rapide que la lecture. Bien que ceci soit du provisoire, (je pense avoir trouvé quelqu'un pour réaliser un premier prototype des cartes audio linux cette après midi), cette opération permet de lire en instantané le format "jo" sur une carte audio PCM,
Je posterai une meilleur solution dès que j'aurai le temps de la mettre au point, mais effectivement chercher un meilleur type était un excellent conseil.
J'ai remarqué depuis que j'utilise le C qu'il y avait à l'intérieur de nombreuses erreurs logiques, que ce soit dans les boucles avec l'initialisation des variables, avec des déformations de ce qui devrai être fait qui donne autre chose et qui doit être corrigé empiriquement en écrivant des lignes illogiques mais qui marchent. Je connais au moins neuf méthodes de faire une addition sur des octets, je ne comprends pas pourquoi le C ne nous laisse pas choisir celle qui nous convient le mieux selon nos lignes de codes. En d'autres mots, il y a peut être quelque chose à améliorer dans le langage C, surtout que je le trouve fort sympathique car il me permet d'écrire les actions comme je les pense. Et en plus hormis ces petits défaut, j'ai l'impression de maitriser mon code.
Cordialement


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#10 Le 12/09/2011, à 06:01

temps

Re : [résolu] Comment limiter une opération en langage C

Ok, voici le code qui marche bien, l'autre n'avait pas assez de précision et je confirme la vitesse d'exécution n'a plus rien à voir avec ce qui se trouve dans la math.h

float jj;

jj = (-boucle/nbdepoints);

ote1 = ote * (1 - ( 1 + jj + (jj*jj*0.5) + (jj*jj*jj*0.1667)+ (jj*jj*jj*jj*0.04167)+ (jj*jj*jj*jj*jj*0.008333)+ (jj*jj*jj*jj*jj*jj*0.0013888889
)+ (jj*jj*jj*jj*jj*jj*jj*0.0001984127)));

et je travaille bien en pourcentage entre presque "0" et presque"1" sur la valeur de la variable "ote"

On peut même améliorer le code en créant un tableau pour les faibles valeurs de nbdepoints qui représente le nombre de base de temps qui reviennent presque tout le temps, ce qui évite la division ne la laissant qu'exceptionnellement quand celle-ci dépasse la quantité de "100" en exemple 1 pour 1 ; 0.5 pour 2, ... et nous pouvons écrire

if ( nbdepoints<100) {jj=-boucle*tab[corespond]}

Dernière modification par temps (Le 12/09/2011, à 06:16)


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne

#11 Le 12/09/2011, à 09:13

Nasman

Re : [résolu] Comment limiter une opération en langage C

Attention au développement limité que tu as trouvé pour la fonction exponentielle

exp(x) = 1 + x + (x*x)/2!+(x*x*x)/3!

Elle suppose que x soit petit devant l'unité.

Pour certaines fonctions il peut aussi être intéressant de faire des calculs itératifs genre :
fonction racine carrée
xn+1=(y+xn.xn)/(2.xn)
soit
x=(y+x²)/2x


PC fixe sous Bionic 64 bits et portable avec Focal 64 bits

Hors ligne

#12 Le 12/09/2011, à 10:01

mjdon

Re : [résolu] Comment limiter une opération en langage C

Je suis tout à fait d'accord. Peut être que remplacer
exp(x) = 1 + x + (x*x)/2!+(x*x*x)/3!+...
par
exp(x) = 1 + x*(1+x/2*(1+x/3*(1+...)))
permettrais aussi de gagner du temps car ça fait moins de multiplications à partir de l'ordre 4. Bien sur, toutes les divisions sont à remplacer par des multiplications comme tu l'as détaillé plus haut.

Dernière modification par mjdon (Le 12/09/2011, à 10:01)

Hors ligne

#13 Le 06/10/2013, à 05:27

temps

Re : [résolu] Comment limiter une opération en langage C

Bonjour,
Je reviens sur cette technique d'écriture des expo sous forme de suite.
Pour faire le point, la technique fonctionne jusqu'à la valeur -1 au delà elle ne fonctionne plus
Je travaille entre 0 et 1, puisque c'est une position par rapport à une valeur limite qui est obtenue, d'ou l'entrée des expo sera toujours négative.
Pour :
]0;-1[ c'est ok
[-1; -...   il y a problème avec la suite mais la classe math en C c'est faire en puisant d'énormes ressources

En fait, j'ai écris l'entrée originale pour l'expo de la class math, peut-être que la solution serait de trouver une technique qui garde la forme de la courbe tout en étant compatible avec l'écriture sous forme de suite. En d'autres mots, avoir en entrée que des valeur qui n'atteignent pas -1 mais qui gardent la forme expo

En dernier recours il reste la technique des tableaux que j'avais utilisé à une époque. D'un point de vue rapidité, elle était aussi très efficace et la taille des tableaux conséquente
soit 256 tableaux comportant 256 cas chacun (en simplifiant on doit pouvoir en retirer une bonne partie puisqu'il n'existe que 256 réponses possibles sur le dernier synthé car il ne travaille que sur 1 octet que ce soit pour les durées ou les amplitudes.

Cordialement


Parce que l'USB bootable est le support des systèmes experts,
Parce que l'USB bootable contient sa propre image au démarrage.
L'USB bootable permet de créer un monde à la dimension de son imagination
https://www.letime.net

Hors ligne