ABCDEFGHIJKLMNOPQRSTUVWXYZ

larr Messages postés 38 Date d'inscription mercredi 18 juin 2003 Statut Membre Dernière intervention 3 février 2010 - 24 juin 2004 à 03:27
blueperfect Messages postés 234 Date d'inscription mardi 13 novembre 2007 Statut Membre Dernière intervention 21 novembre 2013 - 25 août 2008 à 19:36
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/23853-abcdefghijklmnopqrstuvwxyz

blueperfect Messages postés 234 Date d'inscription mardi 13 novembre 2007 Statut Membre Dernière intervention 21 novembre 2013
25 août 2008 à 19:36
Je mets 9 car il manque l'optimisation, sinon, c'est de la bombe baby !
Marneus Calgar Messages postés 39 Date d'inscription mardi 3 octobre 2000 Statut Membre Dernière intervention 10 juin 2005
2 juin 2005 à 17:11
Le vrai goulot d'étranglement dans ton code c'est effectivement l'accès au Canvas.pixels[] qui est très long... Ce serait beaucoup plus rapide avec des accès direct à coup de ScanLine sur un Bitmap qui servirait de buffer...

Regarde ici si tu ne sais pas comment on fait pour utiliser la propriété ScanLine :
http://www.efg2.com/Lab/ImageProcessing/Scanline.htm
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
10 avril 2005 à 16:05
ah oui et c'est pas du bump mapping, jsuis vraiment une banane lol... le bump mapping c'est un procédé en 3d pour rendre une scène un peu plus réaliste, rien à voir quoi.

ça je lappelerai plutot effet de boule par un glandu ;-)
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
10 avril 2005 à 16:02
ué en effet, jvois mieux cque c'est le MMX maintenant... bah cte source faudrait encore lui virer l'utilisation de .Pixels[] et yaller au buffer direct avec un SetDIBits pour que se soit opti au max ;-)

erf lol c marrant de voir ses sources après de longs mois...

++Twis;
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
10 août 2004 à 16:35
humm dans ce cas c'est quoi les instructions MMX? est ce que donc FCOS est présent sur tous les processeurs (notamment les vieux)? est ce qu'il est plus rapide que le cos fourni par delphi?

lien avec plus d'infos sur ce que qu'est le MMX?

Merci bcp, Twis
SeVeN757 Messages postés 2 Date d'inscription dimanche 6 avril 2003 Statut Membre Dernière intervention 10 août 2004
10 août 2004 à 11:13
c'est pas des instructions MMX, c'est des instructions FPU ;)
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
7 juil. 2004 à 17:56
Héhéhé ... ):]
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
7 juil. 2004 à 02:23
mais comme je suis con!!! c'est pas CALL FCOS, c'est FCOS tout court bien sûr!!!

et maintenant ça marche:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
r = 40; // le rayon du cercle en pixels
_1: Single = 1.0;
_157: Single = 1.57;
var
i, j, jj, rx: Integer;
l, p: Single;
begin
BitBlt(temp.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, buf.Canvas.Handle, 0, 0, SRCCOPY);

for j := -r + 1 to r - 1 do
begin
jj := j * j;
rx := Round(sqrt(r * r - jj));
for i := -rx to rx do
begin
l := sqrt(i * i + jj) / r;
asm
FLD _1
FSUB l
FLD _157
FMULP ST(1),ST
FCOS
FDIVR l
FSTP p
WAIT
end;
temp.Canvas.Pixels[X + i, Y + j] := buf.Canvas.Pixels[X + Round(i * p), Y + Round(j * p)];
end;
end;

BitBlt(Form1.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, temp.Canvas.Handle, 0, 0, SRCCOPY);
end;

alors là si y'a qqun qui fait mieux je bouffe ma pantoufle

++ Twis
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
7 juil. 2004 à 02:06
bordel, il connait pas CALL FCOS not pov vieux delphi, pourtant je suis pas fou (finalement ptet que si...), cette instruction existe bel et bien... donc pour l'instant on s'en limite à:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
r = 40; // le rayon du cercle en pixels
var
i, j, jj, rx: Integer;
l, p: Single;
begin
BitBlt(temp.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, buf.Canvas.Handle, 0, 0, SRCCOPY);

for j := -r + 1 to r - 1 do
begin
jj := j * j;
rx := Round(sqrt(r * r - jj));
for i := -rx to rx do
begin
l := sqrt(i * i + jj) / r;
p := l / cos(1.57 * (1 - l));
temp.Canvas.Pixels[X + i, Y + j] := buf.Canvas.Pixels[X + Round(i * p), Y + Round(j * p)];
end;
end;

BitBlt(Form1.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, temp.Canvas.Handle, 0, 0, SRCCOPY);
end;
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
7 juil. 2004 à 01:20
Voilà, j'ai matté sous olly et vlà c'que ça donne:

Donc là c'est avec la variable 'a' (c'est les deux lignes de code avec 'a' et 'p'):

FLD DWORD PTR SS:[EBP-4]
FCHS
FDIV DWORD PTR DS:[452730]
FADD DWORD PTR DS:[452734]
FLD TBYTE PTR DS:[452738]
FMULP ST(1),ST
FSTP DWORD PTR SS:[EBP-8]
WAIT
FLD DWORD PTR SS:[EBP-8]
CALL Project1.0040290C
FMUL DWORD PTR DS:[452730]
FDIVR DWORD PTR SS:[EBP-4]
FSTP DWORD PTR SS:[EBP-C]
WAIT

et là sans la variable 'a':

FLD DWORD PTR SS:[EBP-4]
FCHS
FDIV DWORD PTR DS:[45272C]
FADD DWORD PTR DS:[452730]
FLD TBYTE PTR DS:[452734]
FMULP ST(1),ST
CALL Project1.0040290C
FMUL DWORD PTR DS:[45272C]
FDIVR DWORD PTR SS:[EBP-4]
FSTP DWORD PTR SS:[EBP-8]
WAIT

et donc t'avais raison mec, en fait dans le premier cas y'a 3 lignes en plus:

FSTP DWORD PTR SS:[EBP-8]
WAIT
FLD DWORD PTR SS:[EBP-8]

qui servent à stocker 'a' en mémoire alors que dans le deuxième cas il n'est pas enregistré en mémoire, le calcul se fait directement avec les registres...

Au passage notez qu'il utilise les instructions MMX (reconnaissable avec le F comme FADD, FMUL ou encore FDIV), donc c vraiment pas mal optimisé... sauf qu'il utilise une pauvre fonction pour le cosinus (le CALL) alors qu'il pourrait utiliser l'instrcuction MMX correspondante: FCOS!!!

Conclusion, la meilleure des optis serait de reprog en assembleur... sauf que les nombres à virgules flottantes en assembleur c'est vraiment, mais alors vraiment la merde... ou alors juste à la place de cos on met asm FCOS [...] end; Bon récapitulons, il faut refaire le l_sur_r, virez la variable a et utiliser FCOS, et après je crois que ça y est!!!

++ Twis
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
7 juil. 2004 à 01:01
bon 2s je regarde sous un debugger comme ça on sera enfin informés...
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
7 juil. 2004 à 00:55
En lisibilité on y gagne (un petit peu) c'est sûr ... En même temps si c'est dans un Cosinus on peut se douter que ça représente (abstraitement) un angle.
Maintenant imagine que le calcul de 'a' et son utilisation soient séparés par beaucoup de code...
Lorsque kkun voit Cos(a) il ne pense pas la même chose que si il voit le calcul direct... Déja il cherche où est calculé 'a' et il ne sait pas immédiatement que cette valeur ne sert qu'une fois.. ca peut être pratique lors de modification de code.

Etant donné les "rêgles" d'optimisation qe tout le monde utilise (plus ou moins) quand je vois deux algorithmes qui font le même boulôt mais l'un qui n'utilise que deux variables et l'autre 36 (je caricature !),
je préfère de loin aller voir le premier... (normalement j'aurais pas à réfléchir deux fois sur le même calcul pour savoir ce qu'il signifie car, dans ce cas, le codeur aura utilisé une variable pour optimiser).

Sinon pour l'exe, à mon avis (qui s'appuie sur une réflexion personnel et non pas sur des connaissances), je pense pas que le compilo est assez intelligent pour détecter qu'il n'y a QU ' une utilisation de 'a' et de faire les changements en conséquence.
Mais si on me dit le contraire je pourrais le croire...
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
6 juil. 2004 à 23:24
bien vu pour le l_sur_r, arf ça fait bcp de ptit changement depuis mon premier code, celui-là je l'avais pas vu donc bien joué! Bon toute façon des optis à ce point c'est pour les fanatiques ça va vraiment rien changer sur un prog (sauf si vous tournez sur un 10Mhrtz :P)

pour la variable a, bah c'est vrai que tu peux la virer, mais ça revient au même je pense au niveau du exe, alors autant en gagner en lisibilité nan?

++ Twis
cs_Zeroc00l Messages postés 367 Date d'inscription lundi 1 avril 2002 Statut Membre Dernière intervention 11 février 2010
6 juil. 2004 à 23:19
on peut pas optimiser les l / r ?

l_sur_r := l / r;

a := 1.57 * (-l / r + 1);
devient :
a := 1.57 - 1.57 * l_sur_r;

p := l / (r * cos(a));
devient :
p := l_sur_r / cos(a);


De même, à quoi sert-il de stocker 'a' alors que l'on ne s'en sert qu'une fois ? ( si on ne tient pas compte de la lisibilité )
TheWhiteShadow Messages postés 135 Date d'inscription mercredi 15 janvier 2003 Statut Membre Dernière intervention 7 avril 2006
24 juin 2004 à 03:33
thx larr.

au passage j'ai noté une ptite opti à faire (le j * j, remplacé par la var jj):

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
r = 40; // le rayon du cercle en pixels
var
i, j, jj, rx: Integer;
l, a, p: Single;
begin
BitBlt(temp.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, buf.Canvas.Handle, 0, 0, SRCCOPY);

for j := -r + 1 to r - 1 do
begin
jj := j * j;
rx := Round(sqrt(r * r - jj));
for i := -rx to rx do
begin
// pi / 2 = 1.57 -> optimisation
l := sqrt(i * i + jj);
a := 1.57 * (-l / r + 1);
p := l / (r * cos(a));
temp.Canvas.Pixels[X + i, Y + j] := buf.Canvas.Pixels[X + Round(i * p), Y + Round(j * p)];
end;
end;

BitBlt(Form1.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, temp.Canvas.Handle, 0, 0, SRCCOPY);
end;
larr Messages postés 38 Date d'inscription mercredi 18 juin 2003 Statut Membre Dernière intervention 3 février 2010
24 juin 2004 à 03:27
Code vraiment bon
ça fait stilé pour certain truc :p
Rejoignez-nous