Pas sûr d'avoir compris... le calcul que tu faisais retournait toujours la même chose, et le compilo a shunté le calcul?
Pas sûr d'avoir compris... le calcul que tu faisais retournait toujours la même chose, et le compilo a shunté le calcul?
Yep c'est ça. En gros le compilo à codé l'équivalent de :
à la place du calcul à faire.Code:long f() { return 125025000000; }
Ce qui est évidement plus rapide .
Rien ne me choque moi, je suis un scientifique ! - I. Jones
En même temps c'est pas un peu idiot de passer du temps à écrire puis optimiser un programme de calcul dont on connait déjà le résultat ?
(disclaimer : cette phrase sarcastique peut pourtant être souvent appliquée au premier degré dans la vraie vie )
C'est sûr que vu comme ça
Plus sérieusement, je me demande comment le compilo fait pour inférer que la fonction est pure. Pas de paramètre d'entrée ça aide à deviner que l'on peut inférer le résultat, mais il ne faut pas que la valeur renvoyée dépende de facteurs externe. Et ça, je trouve épatant que le compilateur le détecte.
J'ai essayé de blouser le compilateur en ajoutant une variable aléatoire dans une fonction et en la retranchant dans une autre : "gcc -01" se fait avoir, mais "gcc -02" détecte la supercherie et inline quand même le résultat de la fonction.
Code:long f(long x, long y, long a) { return x+y-a; } long test() { long sum = 0; int t = rand()*10; printf("%d\n", t); for (long i=1; i<5001; i++) { for (long j=1; j<5001; j++) { sum = sum + f(i, j+t, t); } } return sum; } int main(void) { printf("%ld\n",test()); return 0; }
Dernière modification par Helix ; 10/01/2019 à 17h15.
Rien ne me choque moi, je suis un scientifique ! - I. Jones
Et si tu initialise la seed de ton rand sur un identifiant processeur ou l'heure actuelle ?
Cela ne change rien, "gcc -O2" réalise l'optimisation quand même
Rien ne me choque moi, je suis un scientifique ! - I. Jones
Ben c'est juste le travail du compilateur que de séparer ce qui est connu compile-time et run-time, non?
Mais en lisp, qu'est-ce qui t'empêche de calculer la valeur par macro-expansion pour faire pareil?
Non, son résultat de test renvois toujours la même valeur, peut importe la valeur "a" aléatoire qui est choisie.
C'est la faute à Arteis
Yep. Mais c'est quand même beau à voir.
Je sais faire ça en lisp, mais mon compilo lisp (sbcl) ne sait pas le faire automatiquement au contraire du compilateur c.
Pas tout à fait, la valeur renvoyée par test est bien une constante car la valeur aléatoire ajoutée est retranchée ailleurs.
Rien ne me choque moi, je suis un scientifique ! - I. Jones
Y faut mettre un appel système pour que le compilateur lâche l'affaire.
L'est enragé!
Pas bête l'appel système . Je testerai demain matin.
Rien ne me choque moi, je suis un scientifique ! - I. Jones
En gros, le compilo inline ta fonction f (fonction pure, tout est au vert), puis dans la nouvelle fonction sum tu as (x+(y+t)-t) qu'il réécrit en x+y, c'est totalement legit, l'addition des entiers (int ou long) est parfaitement associative en C.
Si tu faisais la même chose en flottants, normalement le compilo ne devrait pas faire la même manip, vu que (a+b)-b n'est pas toujours égal à a en flottants. Ceci dit, je ne mettrais pas ma main à couper qu'aucun compilo ne puisse le faire...
Et appeler la fonction f via un pointeur de fonction, ça devrait empêcher le compilo de faire l'inlining non?
La programmation est une course entre le développeur, qui s’efforce de produire des applications à l’épreuve des imbéciles, et l’univers qui s’efforce de produire de meilleurs imbéciles... L’univers a une bonne longueur d’avance !!!
J'ai des pages scannés avec une police de caractère pour des vieux afficheurs, les caractères sont représentés comme cela :
Avec plusieurs par page, il y a plus de 100 caractères comme cela, le but est de le transformer en array de bit afin d'être implanté dans le microcontrôleur.Code:Caractere n 00: [ ][ ][ ]██████[ ][ ][ ] [ ][ ]███[ ][ ]███[ ][ ] [ ]███[ ][ ][ ][ ]███[ ] ███[ ][ ][ ][ ][ ][ ]███ ████████████████████████ ████████████████████████ ███[ ][ ][ ][ ][ ][ ]███ ███[ ][ ][ ][ ][ ][ ]███ ███[ ][ ][ ][ ][ ][ ]███
Genre :je connais un peu de python, est il possible de faire cela avec de la reconnaissance de texte ?Code:A = { 0,0,0,1,1,0,0,0, 0,0,1,0,0,1,0,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,1}
J'ai cherché un peu mais il me manque les mots clé je ne sais pas par ou commencer.
Le but est de s'amuser un peu, mais est ce que ça vaut le coup, ou ça sera carrément plus rapide de le faire à la main. Du style même un pro du python et de l'intelligence artificielle mettrait plus de temps à le coder qu'a le faire à la main.
Sinon connaissez vous un bon ECR, car j'ai tenté vite fait avec celui que j'ai sous la main et comme la plupart du temps c'est couplé à un dictionnaire, les mots sont bien reconnus, par contre les caractères sont inutilisable, les scans sont propres par contre.
Dernière modification par moimadmax ; 10/01/2019 à 22h06.
Oui c’est possible, il y avait un jeu (fermé depuis) sur Codingame à ce sujet mais il était plus difficile d’y avoir 100% de reconnaissance.
une balle, un imp (Newstuff #491, Edge, Duke it out in Doom, John Romero, DoomeD again)
Canard zizique : q 4, c, d, c, g, n , t-s, l, d, s, r, t, d, s, c, jv, c, g, b, p, b, m, c, 8 b, a, a-g, b, BOF, BOJV, c, c, c, c, e, e 80, e b, é, e, f, f, f, h r, i, J, j, m-u, m, m s, n, o, p, p-r, p, r, r r, r, r p, s, s d, t, t
Canard lecture
J'ai ajouté des elements par la suite, j'ai un peu merdé lors de l'edition,
Pour revenir au sujet, déjà si ça fait le plus gros du travail, c'est déjà pas mal, surtout si c'est un truc qui se code en 2 heures, car il y en a pour la journée je pense à se taper tous les caractères.
Non, le compilateur sait optimiser ce genre de cas. Par contre si tu mets le pointeur de fonction volatile, là, tu auras l'effet escompté.
https://gcc.godbolt.org/z/jxG17S
Le truc c'est que ce n'est pas vraiment de la reconnaissance de caractère La reconnaissance de caractère tu lui file ce que tu a mis dans ton code (des motifs de caractère divers correspondant à "A" ) et ensuite seulement il pourra te reconnaitre le truc. Ceux qui sont déja bien paramétré te donnerons le texte mais en aucun cas ne te donneront la transformation vers le tableau de pixel du caractère d'origine, puisque ce n'est pas leur taf ^^. Là ça ne va donc pas t'économiser ton travail . Alors que toi le plus chiant à la main c'est pas d'écrire 100 caractères, mais bien le tableau correspondant.
Ce qui va t'économiser du travail c'est par contre de faire un algo simple qui en scannant une case que tu lui donne (le A que tu nous donne en haut par exemple, prédécoupés par toi) te donne le tableau de pixel correspondant. Un bout de code simplissime dont tu lui donne le coin supérieur gauche et inférieur droit et le nombre de case de la largeur du caractère peut très facilement ensuite vérifier la valeur du pixel pour te construire ton tableau en sortie. Ça se code en 10 minutes pour le coups . Après tu devra écrire "A" à la main, mais sur 100 caractère ça va
Si tu veut aller plus loin mais c'est chiant, tu peut écrire ton propre outil qui découpera ta feuille selon tes critères pour le donner à manger à la brique de code du dessus. C'est pas très dur à faire à l'arrache vu que tout est sur des lignes et probablement séparé du même nombre de caractère. Mais faut tout de même écrire un truc qui te trouvera l'orientation de la ligne de base (j'imagine que toute les feuilles ne sont pas parfaitement droite), qui te trouvera la taille des cases (facile ça) et qui ensuite te demandera le centre de la première case pour taffer. Je pense qu'il y en a pour 4/5h de taf pour que ça marche à tout les coups.
L'autre approche, qui peut être plus simple à écrire, c'est d'écrire un véritable algo de segmentation simpliste. En gros ton algo parcours chaque pixel de l'image et lui attribue un identifiant en fonction de ses caractéristiques. (ici, la caractéristiques évidentes c'est si suffisamment de point alentours sont noir ou blanc, alors dans ce cas ça reflétera l'appartenance à une case noire ou blanche de tes caractères). A chaque fois qu'il fait cette opération il vérifie si il n'y a pas des cases connexes qui porte le même ID. Si oui, ben il donne exactement le même ID, sinon il donne un autre ID. Si une case peut avoir deux choix différents (deux cases annexes d'ID différents) alors elle en choisis un et saute de pixel à pixel sur les cases de l’autre ID pour le transformer dans l'ID choisi (c'est l'équivalent du pot de peinture sous Paint si tu veut). Voila voila.
A la fin tu aura les lettres prédécoupés et il deviendra alors simplistes de trouver le coin le plus en haut à droite et le plus en bas à gauche pour le donner à manger au premier bout de code.
Le tout me tiendrais occupé une bonne journée en sachant coder. Donc à voir si c'est bien rentable
Tu me l'aurais dit avant j'aurais fait un TP pour mes élèves en cours de traitement d'image et ils auraient fait le taf pour toi
Dernière modification par Nilsou ; 11/01/2019 à 15h07.
Mais je pensais qu'il voulait au départ tester son code (enfin la perf) avec les optimisations du compilateur? le problème étant de désactiver certaines optimisations mais pas d'autres... j'imagine qu'il doit y avoir des options pour ça, ceci dit, le tout étant de les trouver...
L'idée de la reconnaissance de caractère par logiciel OCR est, vu que le scan est propre, qu'avec une version texte (et non image) pour le coup ça devient très facile de le convertir en array, limite avec notepad remplacer "[ ]"par "0," et "███" par "1," fait déjà une grande partie du travail. Mais la majeur partie des OCR travaillent par dictionnaire et comme ils ne trouvent pas de mots tels que [ ]█[ ][ ][ ][ ]█[ ] dans le dico, ça fais de la merde.
Faut que je tente avec des plus sérieux.
Et je note pour les idées de TP Au cas où. Merci pour tes éclaircissements.
Ben je viens de les donner, avec pragma tu peut désactiver toute option que tu veut du compilateur sur le bout de code que tu veut, ou l'activer, comme tu veut. C'est simple ^^.
- - - Mise à jour - - -
Arf, bah dans ce cas tente un truc comme "ABBYY fine reader", c'est un logiciel pro que j'utilise pour lire les sous titres incrustés dans l'image des animés. Mais ça peut lire tout et n'importe quoi et tu peut lui apprendre tout et n'importe quoi comme dictionnaire. Rien de plus aisé de lui apprendre à reconnaitre les pavé noirs et les trous.
Si tu définis les deux fonctions dans deux unités de compilation (.o) différentes et que tu n'actives pas le mode link-time optimization, ça devrait suffire à empêcher l'inlining et faire ce que tu attends. Ou alors mettre un __attribute__ ((noinline)) à la fonction f. Bien sûr tu payeras le coût de l'appel de fonction à chaque itération, et c'est ça qui va dominer le temps de calcul.
Sinon le mieux est de choisir des benchmarks qui calculent réellement quelque chose...
Je m'insurge ! J'ai pris un Atari ST parce que l'Amiga était trop cher. Chaque machine avait ses avantages et idéalement j'aurais voulu les deux.
J'ai néanmoins été bien déçu par l'Amiga qui avait une facheuse tendance à ne pas proprement sauvegarder sur disquette, vive le multi-tâche moisi. Mais tout ces chips dédiés quel pied
Évidemment
Ceci dit, j'ai fréquemment ce genre de pattern (des doubles ou quadruples boucles qui somment des valeurs). Mon bout de code simplifié n'est pas loin d'être représentatifs des calculs qui m'intéressent réellement. Donc empêcher le compilateur de précalculer pour tester la vitesse d'exécution de doubles boucles n'est pas complètement inutile. En tout cas pour moi
Rien ne me choque moi, je suis un scientifique ! - I. Jones
Oui mais tu peux faire une somme qui ne se simplifie pas trivialement. Là le problème n'est pas que le compilateur précalcule, c'est que comme le petit Gauss, il voit qu'une boucle qui somme les entiers successifs ça ne sert à rien et il la dégage. Et une fois qu'il a dégagé les deux boucles et est ramené à une seule expression, bah il propage les constantes, mais à ce stade ça ne change plus grand-chose.
Si les termes de la série que tu calcules ne sont pas linéaires, le compilateur ne devrait plus arriver à simplifier. Ou plus généralement un calcul que tu ne saurais pas simplifier toi-même.