CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

sqrt() lent?

Virtuality
Virtuality
Niveau 8
30 avril 2005 à 20:18:20

Bonjour,

j´ai une collision à tester, et pour cela j´ai besoin de sqrt().
En fait il s´agit d´une balle qui doit rebondir sur un objet.
Jusqu´à maintenant j´ai testé les collision avec des carrés, malheureusement, ça ne marche pas très bien ( et ce n´est pas très précis).
J´ai donc bien réfléchi et trouvé " la solution".
Voici comment j´ai tenté de gérer ma collision:

for(k=ecran[i][j].x;k<=ecran[i][j].x+64;k++)
{
for(l=ecran[i][j].y;l<=ecran[i][j].y+20;l++)
{
clcball=(k-baballe.x+12)^2 + ( l-baballe.y+12)^2; if(sqrt(clcball)==10)
{

ça " devrait" marcher, malheureusement, ce n´est pas " tout à fait le cas".
En effet la collision bug, mais mon principal ennui, c´est que le jeu est ralenti d´au moins 3x plus!
Y a t-il un moyen pour remédier à ce problème?
Merci

fantometteninja
fantometteninja
Niveau 6
30 avril 2005 à 20:36:53

Concentre toi plutot sur l´algo que les operations.
seulement ENSUITE regarde les endroits ou ça rame.

Et pour déterminer les goulots d´etranglement, utilise un profiler. Cela t´evitera d´optimiser des parties qui n´en ont pas besoin.

sinon, petite astuce pour virer le sqrt().
Tu veux comparer deux distances :
sqrt(clcball) == 10
c´est equivalent à
clcball == 100

au fait, le ^ ne permet pas de calculer des puissances, mais d´effectuer un xor.

Virtuality
Virtuality
Niveau 8
30 avril 2005 à 20:44:25

Oups je vien de vérifier en effet.
Mais comment élever un nombre au carré alors?
Merci

Poubi
Poubi
Niveau 6
30 avril 2005 à 20:58:47

Bonsoir,

Bah, si je suis d´une logique imparable, il suffit simplement de multiplier le nombre par lui même, au lieu de lui imposer un exposant :

a^2 == a*a

Cela fait longtemps que j´ai pas vu du C/C++, alors je laisse dire les autres, mais j´espère t´avoir aidé :O

@+,

Poubi.

fantometteninja
fantometteninja
Niveau 6
30 avril 2005 à 20:59:37

tu dois avoir une fonction pow ou quelque chose du genre dans math.h.

Sinon, petite précision par rapport à ce que j´ai ecrit plus haut.
D´abord tu fais le profilage pour voir les fonctions qui font ramer.
Ensuite tu t´attaque aux algos
et tout à la fin au code en lui-meme.
Mais point de vue optimisation, les compilos font des choses pas mal non plus, alors ne te tracasse pas trop.

thesuperbest
thesuperbest
Niveau 8
30 avril 2005 à 20:59:42

C´est tout simple :

x à la puissance deux est égal à x * x donc d´après ton code : ( k-baballe.x+12)*(k-baballe.x+12)

Virtuality
Virtuality
Niveau 8
30 avril 2005 à 21:13:34

Merci j´ai fais assez d´années de math pour savoir ça^^ :-p
Bon je vais essayer de trouver cette fonction pis sinon je devrais me résoudre a multiplier.

dnob700
dnob700
Niveau 10
01 mai 2005 à 02:41:21

surtout pas : ( k-baballe.x+12)*(k-baballe.x+12) il vaut mieux avoir une variable t:
t=(k-baballe.x+12);

et tu fait t*t sinon il risque d´y avoir plein de calcul inutile fait par ton programme si ton compilo n´est pas assez bon.

JeanYvesYves
JeanYvesYves
Niveau 10
02 mai 2005 à 01:06:55

sqrt est en effet a éviter comme la peste :

Aucune machine actuelle n´est capable de calculer rapidement une racine carrée : aucun algo n´est completement cablé, donc c´est logiciellement calculé ( par dichotomie me semble t il).
A donc en mettre le moins possible !

Plusieurs remarques :
- le ^2 n´est pas du tout ( puissance 2), le compilo va t´y accepter, mais l´opérateur ^ est le XOR, donc rien a voir avec la puissance, postule donc pour le t*t, c´est la meilleure solution ( évite pow() pour faire u tel cas particulier)
- Dnob a raison : précalcule tout ce que tu peux avant : donc le t*t avec l´expression de t calculée avant est correcte.
- autre remarque :
tu testes si ta racine carrée est égale a qq chose : ça veut dire que tu testes, d´une façon, que la " peau" de ta balle". Pour un test plus fiable meme si la balle va plus vite, utilise les inagalités :
if sqrt<10.

Une autre astuce :
tester la collision entre 2 balles est un algo facile et parfait :
- il suffit de tester que la distance entre les 2 centres est inférieure a la somme des rayons de chaque balle :
Exemple :
ta balle A a comme centre Ac, et rayon Ar
ta balle B a comme centre Bc, et rayon Br

tu calcules la distance au carré D = ( Acx-Bcx)²+(Acy-Bcy)²

et tu testes si D < = Ar+Br
si oui, alors collision
si non, alors pas collision

ça marche a tous les coups.

bobrun
bobrun
Niveau 6
02 mai 2005 à 03:25:49

sauf si la vitesse de la balle est trop rapide.

et oui dans ce cas tu peux rater la collision, et tes deux balles se traversent

dnob700
dnob700
Niveau 10
02 mai 2005 à 12:05:36

si ton programme lag tellement qu´entre deux frame successive tes balles se déplace de la longueur de leur diamètre alors il y a peut-être autre chose a revoir.

Quoi que... quantiquement c´est pas impossible.

A ce propos, dans un autre post quelqu´un ( LGV ? ) a dit que calculé des cosinus et autre fonction trigo ne prenait qu´un seul cycle processeur.
Lesdernière table que j´ai vu donnait plutot 20 ou 30 cycles pour ce genre d´instruction ( des fcos, fsin, etc en asm pour les FPU de 486 et +).
Qu´en est-il réellement si quelqu´un le sait ?

Virtuality
Virtuality
Niveau 8
07 mai 2005 à 23:22:53

Merci JeanYvesYves, dsl j´avais pas vu qu´on m´avait encore répondu :)

( Acx-Bcx)²+(Acy-Bcy)²

Vi c´est ce que j´ai mis, mais c´est légèrement différent, étant donné que c´est la collision avec des objets rectangulaires... donc pas de rayon^^

J´ai tenté maintes fois de revoir mon code, je n´obtient rien de satisfaisant.
Il est temps que je m´avoue vaincu et que je demande un coup de main de plus :-p
Voila mon dernier code :

ecran[i][j].x=150+(i*66);
ecran[i][j].y=100+(j*25);

SDL_BlitSurface(blok_solide,NULL,screen,&[i][
j]);
for(k=ecran[i][j].x;k<=ecran[i][j].x+64;k++)
{
for(l=ecran[i][j].y;l<=ecran[i][j].y+20;l++)
{
carre=k-baballe.x+12;
carre2=l-baballe.y+12;

clcball=(carre*carre + carre2*carre2);
if(clcball<100)
{
if((baballe.y==l && ( baballe.x>ecran[i][j].x && baballe.x<ecran[i][j].x+64))||(baballe.y==l+20 && ( baballe.x>ecran[i][j].x && baballe.x<ecran[i][j].x+64)))
{
sy=-sy;
/ /play_song("sons/touche.mp3",0);
/ /points+=20;
ecran_behind[i][j]=3;
}
else if((baballe.x==k && ( baballe.y>ecran[i][j].y && baballe.y<ecran[i][j].y+20))||(baballe.x==k+64 && ( baballe.y>ecran[i][j].y && baballe.y<ecran[i][j].y+20)))
{
sx=-sx;
ecran_behind[i][j]=3;
}
}

ecran[i][j] correspond aux coordonnées de ecran_behind[i][j], qui lui, indique l´état de l´objet ( détruit, visible, etc..)
Pour trouver les coordonées de ecran[i][j] correspondant, à l´ecran_behind un simple calcul :
150+(i*66)
( hum, simple quand on le voit pas quand faut y penser^^).

Je suis complètement crevé, j´en peu plus, et j´ai envie de passer à autre chose que cette stupide gestion des collision ( pourtant chaque nuit je me dis : " j´ai la solution!", et non.... ça me rend dingue!)

Si qqn peut m´aider à faire fonctionner ce code :)
Pour le moment la balle passe à travers au lieu de rebondir ( mais détruit l´objet tout de même), parfois il passe comme si de rien n´était, parfois ça marche, bref, on dirait que ma gestion marche sur un rand()!
Merci d´avance :)

LGV
LGV
Niveau 28
07 mai 2005 à 23:51:12

dnob700 : depuis le 486, les choses ont bcp changé ; à l´époque y´avait les SX et les DX, et le module FPU était relativement dissocié de la partie 16bits " integer".
Ajd, la longueur des pipelines, leur multiplicité, les jeux d´instructions étendues, les technos comme l´HT, et j´en passe, font que oui, des instructions comme des sin/cos ne prennent *virtuellement* que qq cycles CPU ( voire 1 seul comme j´ai pu, mais tres dépendant du contexte et de l´état du CPU à cet instant).
Qu´est-ce que j´entends par " virtuellement" ? et bien qu´en pratique le calcul demande toujours des choses relativement compliquées, mais qu´en pratique ça coute tres peu, à peine plus que qq instructions élémentaires, et les performances s´en ressentent donc tres peu. ( par ex. avec le SSE, tu les calcules par 2 pour le meme cout ; tu peux meme deleguer au GPU qui lui sait faire ces choses tres rapidement). Bien sur on peut toujours mettre l´archi en defaut, et faisant des choses contraires ( qui vont forcer des reinit de l´état FPU, la non-parallélisation des calculs, vider le prefetch, etc.) et ça devient catastrophique. Mais en utilisation raisonnée, ça marche pour le mieux. Tu remarqueras d´ailleurs qu´on ne trouve plus de tables indiquant le nb de cycles pour les CPU apres les PII ; tout simplement parce que ça dépend trop du contexte, de la parallelisation ou non des instructions, etc. Par contre, on trouve des guides sur comment pondre du bon code pour tirer le meilleur profit de l´archi et faciliter le boulot des compilos pour exploiter les dernières fonctionnalités.
Ce qu´il faut retenir, c´est que depuis qq années, sur des CPU récents, le compromis perf/souplesse ne joue plus en faveur des LUT, et c´est s´emmer.. pour rien que d´en passer par là. ( meme sur PS2 à 233Mhz, avec l´archi et la petite quantité de mémoire, le compromis est plus interessant dans le cas des instructions trigo que dans celui des LUTs)
Evidemment, il reste des TREEES nombreuses choses encore tres couteuses, notamment les sqrt dont il était ici initialement question.

LGV
LGV
Niveau 28
08 mai 2005 à 00:03:30

pour le SSEx, je parlais du sqrt, je ne crois pas qu´il y ait de choses pour les fonctions trigo en SSEx, à vérifier.
au passage, ex concret : avec un __m128_mm_rsqrt_ps ou un __m128_mm_sqrt_ps tu calcules les racines carrées ( ou leur inverse, plus rapide à calculer et plus souvent utilisé) par packs de 4. Bon faut s´arranger ( ou faire que le compilo s´arrange) pour les calculer par 4, mais quand ça tourne bien, c´est du rapide !
Meme si sa méthode de codage ne permet pas d´exploiter entièrement de telles possibilités, de mon point de vue mieux vaut rester sur qqch d´un peu moins rapide et remettre à plus tard ces finesses d´implémentations, plutot que s´engager dans une voie caduque en voulant subsituer à l´archi des méchanismes maisons. Ce dernier point n´est d´ailleurs pas forcément inutile, au contraire, et je pense que le programmeur conscient doit avoir les deux méthodes dans sa besace : tirer au mieux parti de l´archi lorsque c´est possible, et dans qq cas particuliers où ce n´est pas envisageable, utiliser ses propres outils pour palier une déficience. Mais ce genre de considération me semble hors de la portée initiale du topic :)

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de Jeux
  • Programmation
  • Création de sites web
  • Linux
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment