Conversion float -> int

Soyez le premier à donner votre avis sur cette source.

Snippet vu 15 310 fois - Téléchargée 27 fois

Contenu du snippet

Pendant que j'écrivais un prog qui faisanit pas mal de conversion float vers int, j'ai regardé le code assembleur généré et je me suis aperçu que le prog passait son temps à modifier le registre de contrôle du FPU avant de faire sa conversion et perdait ainsi tu temps.

j'ai voulu vois ce que j'obtenai en faisant moi-même la conversion :
un float est représenté sous 32 bits comme ceci :
signe*1.m * 2^exp

bit 31 : signe.
bits 30..23 : exposant+127.
bits 22..0 : partie fractionnaire de la mantisse.

Source / Exemple :


#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

//******************************************************************
//******************************************************************
int ftoi(float f)
{
	DWORD dw = *((DWORD*) &f);
	if(dw == 0)
		return 0;

	char exp = (char) (((dw>>23)&0xFF)-127);
	if(exp < 0 || exp > 23)
		return 0;
	
	int val = (1<<exp) + ((dw&0x7FFFFF)>>(23-exp));
	if(dw&0x80000000)
		return -val;
	else
		return val;
}

#define NB_BCL	100000000

float floatVal;
int intVal;

//******************************************************************
//******************************************************************
int main()
{
	srand(GetTickCount()^GetCurrentProcessId());

	DWORD dwDeb1 = GetTickCount();
	for(int i = 0; i < NB_BCL; i++)
	{
		int val = rand();
		floatVal = val/3.14159f;
		intVal = (int) (float)floatVal;
	}
	DWORD dwFin1 = GetTickCount();

	DWORD dwDeb2 = GetTickCount();
	for(int j = 0; j < NB_BCL; j++)
	{
		int val = rand();
		floatVal = val/3.14159f;
		intVal = ftoi(floatVal);
	}
	DWORD dwFin2 = GetTickCount();

	printf("%d\r\n", dwFin1-dwDeb1);
	printf("%d\r\n", dwFin2-dwDeb2);

	system("PAUSE");
	return 0;
}

Conclusion :


résultat (celeron 800MHz):
conversion brute : 12s
avec ftoi : 6s
avec ftoi inline : 4s

A voir également

Ajouter un commentaire

Commentaires

ccarniel
Messages postés
23
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
17 octobre 2004

non un XP1700+ tourne à 1466MHz.
Sinon les ratio par rapport au Celeron 800 ne me choquent pas plus que ça.

J'ai utilisé Studio.Net pour changer mes paramètres, celui qui dépote vraiment c'est celui qui active SSE, bien plus que le type de processeur.
Ca se trouve sous C/C++ (Code Generation) : Enable Enhanced Instruction Set. Là, j'ai activé SSE.
Je ne sais pas si c'était déjà dispo sous VC++ 6.

Voili, voilou, bonne nuit, je vais me coucher :)
ymca2003
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
ccarniel : j'ai juste une petite question, ton processeur il tourne à 1700 MHz?
si oui comment ça se fait qu'avec la fonction ftoi il n'est pas plus rapide que ça?

j'ai essayé en modifiant les paramètres du projet sur le type de processeur et ça change que dal (au passage les essais sont en mode Release avec VC 6.0)
ccarniel
Messages postés
23
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
17 octobre 2004

Si je prends ton code tel quel, j'obtiens les temps suivants:
4356 en calcul flottant
4166 en passant par ta routine ftoi
donc ta fonction semble mieux que ce qui est prévu par le compilateur.
Ma config est un Athlon XP1700+, mais peu importe.

Toutefois, si je modifie les paramètres du projet et que je lui permet d'utiliser le jeu d'instruction PIII et surtout les instructions SSE (présentes sur les Athlon XP), alors j'obtiens:
3155 en calcul flottant
4336 en passant par ta routine ftoi

Ce que je veux dire par là, c'est que l'optimisation du code n'était que dans ta routine C, le compilateur n'avait pas le droit d'utiliser tout son potentiel d'optimisation (pour pouvoir tourner sur 386 par exemple, c'est nécessaire).

A l'avenir si tu cibles des machines récentes dans tes programmes regarde aussi du coté des paramètres du projet, il y a aussi des choses à optimiser là :)

En tous cas, la démarche est bonne, il faut toujours être curieux.
BruNews
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
17
Salut,

http://www.movsd.com/
tu pourras y prendre MASM32 et dans son dossier Help se trouve Agner.hlp qui detaille tout cela et plus encore.

Exemple a suivre dans tous les cas, ne pas craindre d'aller voir ce que produit le compilo et tenter de faire mieux ne peut pas nuire.

ciao...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.