• [^] # Re: PA-RA-LLELE!

    Posté par (site web personnel) . En réponse à la dépêche Traitement d'images : Quand G'MIC 1.3.0 s'invite dans GIMP. Évalué à 8.

    Bon ce genre de question revient toujours. Je commence à avoir l'habitude. Je vais te répondre très rapidement sur le pourquoi du comment :

    - D'abord, G'MIC se compile très bien en parallèle, je le fais comme ça chez moi :


    dtschump@gemino:~/work/src/gmic/src$ make -j
    make "CFLAGS+=-Dcimg_display=1 -I/usr/X11R6/include" "LDFLAGS+=-L/usr/X11R6/lib -lX11 -lpthread -lswscale" "STRIP_EXE=1" gmic
    g++ -o gmic4gimp.o -c gmic.cpp -Dgmic_minimal -Dcimg_display=0 -Wall -W -O3 -ffast-math -fno-tree-pre -Dcimg_use_fftw3
    make "CFLAGS+=-Dcimg_display=1 -I/usr/X11R6/include" "LDFLAGS+=-L/usr/X11R6/lib -lX11 -lpthread" "STRIP_EXE=1" gmic
    make[1]: Entering directory `/users2/prof/dtschump/work/src/gmic/src'
    g++ -o gmic_bool.o -c gmic.cpp -Dgmic_separate_compilation -Dgmic_bool -Dcimg_display=1 -I/usr/X11R6/include -Wall -W -O3 -ffast-math -fno-tree-pre -Dcimg_use_xshm -Dcimg_use_xrandr -Dcimg_use_png -Dcimg_use_jpeg -Dcimg_use_tiff -I/usr/include/ffmpeg -Dcimg_use_ffmpeg -Dcimg_use_zlib -Dcimg_use_magick -Dcimg_use_fftw3
    g++ -o gmic_uchar.o -c gmic.cpp -Dgmic_separate_compilation -Dgmic_uchar -Dcimg_display=1 -I/usr/X11R6/include -Wall -W -O3 -ffast-math -fno-tree-pre -Dcimg_use_xshm -Dcimg_use_xrandr -Dcimg_use_png -Dcimg_use_jpeg -Dcimg_use_tiff -I/usr/include/ffmpeg -Dcimg_use_ffmpeg -Dcimg_use_zlib -Dcimg_use_magick -Dcimg_use_fftw3
    g++ -o gmic_char.o -c gmic.cpp -Dgmic_separate_compilation -Dgmic_char -Dcimg_display=1 -I/usr/X11R6/include -Wall -W -O3 -ffast-math -fno-tree-pre -Dcimg_use_xshm -Dcimg_use_xrandr -Dcimg_use_png -Dcimg_use_jpeg -Dcimg_use_tiff -I/usr/include/ffmpeg -Dcimg_use_ffmpeg -Dcimg_use_zlib -Dcimg_use_magick -Dcimg_use_fftw3


    ... et j'en passe (j'ai également 16 coeurs sur cette machine).
    La compilation prend alors environ 10 minutes sur un P4, 3Ghz à 16Go de RAM. On n'a pas mis la compilation parallèle par défaut car ca prend effectivement beaucoup de RAM (mais pas pour les raisons que tu invoques). Bref, essaye d'aller dans 'gmic/src' et de lancer 'make -j', ca devrait le faire, y a pas de raison : G'MIC a été prévu pour être compilé en parallèle.

    Quant à CImg, sa structure parait bizarre à beaucoup de monde, mais c'est finalement très logique quand on ne fait pas juste survoler le truc : c'est une bibliothèque massivement "template", donc ne pouvant pas se 'pré-compiler' facilement en objets (puisque l'ensemble des fonctions et des types à compiler n'est connue que lors de la compilation du programme l'utilisant). Par ailleurs, pré-compiler toutes les fonctions pour les types les plus courants n'étant pas une bonne idée non plus, étant donné le nombre important de fonctions (qui ne seront pas toutes utilisées de toute facon), et la taille des fichiers objets qui en résulteraient.
    Je ne remets pas en cause ce que tu as appris à l'école, mais le cas des bibliothèques template en C++ est un truc un peu particulier de ce point de vue (voir la STL ou Boost).

    Pour finir, on pourrait très bien diviser le fichier CImg.h en pleins de petits fichiers. Je ne le fais pour les raisons suivantes :

    Ca n'irait pas plus vite à compiler (les classes de CImg étant dépendantes les unes des autres, contrairement à la STL, tous les headers de CImg ainsi divisés seraient nécéssaires à la compilation du projet de toute façon. Il faudrait juste faire 20 includes au lieu d'un seul).
    De même ca ne prendrait pas moins de RAM (pour les mêmes raisons).
    Ca ne serait pas spécialement plus facile à maintenir (CTRL+S dans Emacs ou n'importe quel IDE C++ digne de ce nom permet d'aller à la définition d'une fonction rapidement, c'est pas un souci. Par ailleurs, le fichier est très bien structuré si tu regardes bien).

    Au final, aucun avantage donc à diviser ce fichier, à part faire plaisir à quelques personnes aux préjugés un peu tenaces sur la "beauté" de ce que doit être un code (ce terme revient souvent, ca me fait doucement rigoler).

    G'MIC existe grâce à CImg, et à profite de sa généricité. G'MIC peut lire et traiter des images de bool, float, int, etc... Avec à chaque fois des fonctions de traitements spécialisés pour chaque type (un blur d'une image de char ne vas pas avoir besoin de convertir d'abord l'image en float puis la recaster en char). Ce sont des propriétés essentielles au fait que G'MIC soit générique. On ne peut pas avoir le beurre et l'argent du beurre : cette généricité se paye par un temps de compilation un peu plus important que pour des projets plus classiques.

    Après j'aurais pu baser G'MIC sur autre chose que CImg, mais bon, moi j'aime bien CImg, c'est pratique à utiliser, c'est beau, c'est top moumoute :), et ca permet de faire pleins de choses en quelques lignes (G'MIC ne fait 'que' 3825 lignes, c'est très faible par rapport au nombre de choses qu'il sait faire).

    Après, si tu veux t'amuser, tu peux toujours essayer de décomposer dans tous les sens, si tu gagnes 1/100 de seconde sur le temps de compilation ou sur la RAM utilisée, fais moi signe, ça m'intéresse.

    David.