Sur une machine moderne ?
Sur une machine moderne ?
Sur une machine moderne ?
On 27 Sep 2005 06:45:38 -0700, "kanze" :Sur une machine moderne ?
Qu'entends-tu par "machine moderne" ? Une machine incapable de
travailler en 8 ou 16 bits, ou une machine trop rapide pour
que ça ait de l'importance ?
Soit une image en couleurs, que tu veux passer en valeurs de gris.
Pour chaque pixel, tu fais la moyenne de trois entiers non signés de 8
bits (les composantes rouge, bleue et verte du pixel). Faire ça en C++
(du style (pixel[0]+pixel[1]+pixel[2])/3 ) n'est pas possible -- trop
long, du moins quand tu veux afficher 24 images de taille respectable
toutes les secondes.
On 27 Sep 2005 06:45:38 -0700, "kanze" <kanze@gabi-soft.fr>:
Sur une machine moderne ?
Qu'entends-tu par "machine moderne" ? Une machine incapable de
travailler en 8 ou 16 bits, ou une machine trop rapide pour
que ça ait de l'importance ?
Soit une image en couleurs, que tu veux passer en valeurs de gris.
Pour chaque pixel, tu fais la moyenne de trois entiers non signés de 8
bits (les composantes rouge, bleue et verte du pixel). Faire ça en C++
(du style (pixel[0]+pixel[1]+pixel[2])/3 ) n'est pas possible -- trop
long, du moins quand tu veux afficher 24 images de taille respectable
toutes les secondes.
On 27 Sep 2005 06:45:38 -0700, "kanze" :Sur une machine moderne ?
Qu'entends-tu par "machine moderne" ? Une machine incapable de
travailler en 8 ou 16 bits, ou une machine trop rapide pour
que ça ait de l'importance ?
Soit une image en couleurs, que tu veux passer en valeurs de gris.
Pour chaque pixel, tu fais la moyenne de trois entiers non signés de 8
bits (les composantes rouge, bleue et verte du pixel). Faire ça en C++
(du style (pixel[0]+pixel[1]+pixel[2])/3 ) n'est pas possible -- trop
long, du moins quand tu veux afficher 24 images de taille respectable
toutes les secondes.
Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
nouvelle_valeur[vert]-ancienne_valeur[vert])
Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
nouvelle_valeur[vert]-ancienne_valeur[vert])
Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
nouvelle_valeur[vert]-ancienne_valeur[vert])
On 28 Sep 2005 00:27:24 -0700, "kanze" :Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
J'avais choisi l'exemple un peu au hasard, et j'avoue qu'il
était mauvais. Mais je viens de tomber sur un exemple typique
et réel.
J'ai deux images en RVB (1 octet rouge, 1 octet vert, 1 octet
bleu) -- en fait deux frames successives dans une vidéo.
Je dois appliquer l'algorithme suivant : aucune composante ne
peut varier plus de deux fois plus vite que les autres. En
d'autres termes, et en simplifiant :
si (nouvelle_valeur[rouge]-ancienne_valeur[rouge]2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
Le "alors" ne m'inquiète pas trop ici, car le cas est peu
fréquent ; je ne m'intéresse qu'à la condition. Je peux la
réécrire ainsi :
si ( (nouvelle_valeur[rouge]-ancienne_valeur[rouge]) / 2nouvelle_valeur[vert]-ancienne_valeur[vert])
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup
faire de l'arithmétique en 8 bits, et ne pas avoir à faire des
conversions entre les entiers sur 1 octet et les entiers sur 4
octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas mot,
c'est 10 fois plus lent que ce à quoi on pourrait s'attendre
pour un tel filtre) ; il va donc falloir que je trouve une
autre solution.
On 28 Sep 2005 00:27:24 -0700, "kanze" <kanze@gabi-soft.fr>:
Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
J'avais choisi l'exemple un peu au hasard, et j'avoue qu'il
était mauvais. Mais je viens de tomber sur un exemple typique
et réel.
J'ai deux images en RVB (1 octet rouge, 1 octet vert, 1 octet
bleu) -- en fait deux frames successives dans une vidéo.
Je dois appliquer l'algorithme suivant : aucune composante ne
peut varier plus de deux fois plus vite que les autres. En
d'autres termes, et en simplifiant :
si (nouvelle_valeur[rouge]-ancienne_valeur[rouge]
2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
Le "alors" ne m'inquiète pas trop ici, car le cas est peu
fréquent ; je ne m'intéresse qu'à la condition. Je peux la
réécrire ainsi :
si ( (nouvelle_valeur[rouge]-ancienne_valeur[rouge]) / 2
nouvelle_valeur[vert]-ancienne_valeur[vert])
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup
faire de l'arithmétique en 8 bits, et ne pas avoir à faire des
conversions entre les entiers sur 1 octet et les entiers sur 4
octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas mot,
c'est 10 fois plus lent que ce à quoi on pourrait s'attendre
pour un tel filtre) ; il va donc falloir que je trouve une
autre solution.
On 28 Sep 2005 00:27:24 -0700, "kanze" :Je ne comprends pas le « trop long ». Qu'est-ce que le
compilateur va faire de plus que tu ne dois pas faire en
assembleur ?
J'avais choisi l'exemple un peu au hasard, et j'avoue qu'il
était mauvais. Mais je viens de tomber sur un exemple typique
et réel.
J'ai deux images en RVB (1 octet rouge, 1 octet vert, 1 octet
bleu) -- en fait deux frames successives dans une vidéo.
Je dois appliquer l'algorithme suivant : aucune composante ne
peut varier plus de deux fois plus vite que les autres. En
d'autres termes, et en simplifiant :
si (nouvelle_valeur[rouge]-ancienne_valeur[rouge]2 * nouvelle_valeur[vert]-ancienne_valeur[vert])
alors nouvelle_valeur[rouge]= (ce qu'il faut)
Le "alors" ne m'inquiète pas trop ici, car le cas est peu
fréquent ; je ne m'intéresse qu'à la condition. Je peux la
réécrire ainsi :
si ( (nouvelle_valeur[rouge]-ancienne_valeur[rouge]) / 2nouvelle_valeur[vert]-ancienne_valeur[vert])
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup
faire de l'arithmétique en 8 bits, et ne pas avoir à faire des
conversions entre les entiers sur 1 octet et les entiers sur 4
octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas mot,
c'est 10 fois plus lent que ce à quoi on pourrait s'attendre
pour un tel filtre) ; il va donc falloir que je trouve une
autre solution.
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup faire
de l'arithmétique en 8 bits, et ne pas avoir à faire des conversions
entre les entiers sur 1 octet et les entiers sur 4 octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur et sans
chercher à optimiser) prend un temps fou (au bas mot, c'est 10 fois
plus lent que ce à quoi on pourrait s'attendre pour un tel filtre) ;
il va donc falloir que je trouve une autre solution.
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup faire
de l'arithmétique en 8 bits, et ne pas avoir à faire des conversions
entre les entiers sur 1 octet et les entiers sur 4 octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur et sans
chercher à optimiser) prend un temps fou (au bas mot, c'est 10 fois
plus lent que ce à quoi on pourrait s'attendre pour un tel filtre) ;
il va donc falloir que je trouve une autre solution.
Tous les nombres restent sur 8 bits ; j'aimerais donc beaucoup faire
de l'arithmétique en 8 bits, et ne pas avoir à faire des conversions
entre les entiers sur 1 octet et les entiers sur 4 octets.
Le programme, tel que je l'ai écrit (en C++, sans assembleur et sans
chercher à optimiser) prend un temps fou (au bas mot, c'est 10 fois
plus lent que ce à quoi on pourrait s'attendre pour un tel filtre) ;
il va donc falloir que je trouve une autre solution.
Fabien LE LEZ writes:Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas
mot, c'est 10 fois plus lent que ce à quoi on pourrait
s'attendre pour un tel filtre) ; il va donc falloir que je
trouve une autre solution.
C'est le genre de probleme ou on est normalement plus limite
par la bande passante que par le calcul. C'est en tout cas la
ou je regarderais en premier.
Fabien LE LEZ <gramster@gramster.com> writes:
Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas
mot, c'est 10 fois plus lent que ce à quoi on pourrait
s'attendre pour un tel filtre) ; il va donc falloir que je
trouve une autre solution.
C'est le genre de probleme ou on est normalement plus limite
par la bande passante que par le calcul. C'est en tout cas la
ou je regarderais en premier.
Fabien LE LEZ writes:Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Le programme, tel que je l'ai écrit (en C++, sans assembleur
et sans chercher à optimiser) prend un temps fou (au bas
mot, c'est 10 fois plus lent que ce à quoi on pourrait
s'attendre pour un tel filtre) ; il va donc falloir que je
trouve une autre solution.
C'est le genre de probleme ou on est normalement plus limite
par la bande passante que par le calcul. C'est en tout cas la
ou je regarderais en premier.
Jean-Marc Bourguet wrote:Fabien LE LEZ writes:Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Je ne suis pas sûr. Si le compilateur déroule la boucle, pour en
faire quatre pas chaque fois, puis réordonne le code de façon à
ce que les lectures de chaque table se suivent, il y a de fortes
chances qu'à la lecture des octets après le premier, le
processeur trouve que les données sont déjà là, et n'accède pas
à la mémoire pour les autres.
Ceci dit, le fait de travailler sur 32 bits à la place de 8 n'y
change pas forcement grand chose.
S'il déclare les données dans une struct de quatre octets,
genre :
struct { uint8_t red,green,blue,fill ; } ;
et que le compilateur est assez intelligent pour lire le struct
dans un seul coup, et le tenir dans un régistre, ça dévise le
nombre d'accès par quatre. (Seulement, sur un Intel, les deux
octets de poids fort d'un registre ne sont pas accessible
directement comme octets. Du coup, il faut des décalages et des
masquages, qui ne vont pas accélérer le traitement non plus.)
Jean-Marc Bourguet wrote:
Fabien LE LEZ <gramster@gramster.com> writes:
Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Je ne suis pas sûr. Si le compilateur déroule la boucle, pour en
faire quatre pas chaque fois, puis réordonne le code de façon à
ce que les lectures de chaque table se suivent, il y a de fortes
chances qu'à la lecture des octets après le premier, le
processeur trouve que les données sont déjà là, et n'accède pas
à la mémoire pour les autres.
Ceci dit, le fait de travailler sur 32 bits à la place de 8 n'y
change pas forcement grand chose.
S'il déclare les données dans une struct de quatre octets,
genre :
struct { uint8_t red,green,blue,fill ; } ;
et que le compilateur est assez intelligent pour lire le struct
dans un seul coup, et le tenir dans un régistre, ça dévise le
nombre d'accès par quatre. (Seulement, sur un Intel, les deux
octets de poids fort d'un registre ne sont pas accessible
directement comme octets. Du coup, il faut des décalages et des
masquages, qui ne vont pas accélérer le traitement non plus.)
Jean-Marc Bourguet wrote:Fabien LE LEZ writes:Tous les nombres restent sur 8 bits ; j'aimerais donc
beaucoup faire de l'arithmétique en 8 bits, et ne pas avoir
à faire des conversions entre les entiers sur 1 octet et les
entiers sur 4 octets.
Les seuls cas ou j'ai l'impression qu'il y a moyen de gagner
avec des processeurs "normaux" en travaillant en 8 bits, c'est
quand il y a moyen d'utiliser les instructions vectorielles
(dites "multimedia", ce n'est pas les instructions
vectorielles des processeurs Cray et autres). Dans les autres
cas, les chemins de donnees et les unites fonctionnelles etant
en 32 bits, il y aura conversion.
Je ne suis pas sûr. Si le compilateur déroule la boucle, pour en
faire quatre pas chaque fois, puis réordonne le code de façon à
ce que les lectures de chaque table se suivent, il y a de fortes
chances qu'à la lecture des octets après le premier, le
processeur trouve que les données sont déjà là, et n'accède pas
à la mémoire pour les autres.
Ceci dit, le fait de travailler sur 32 bits à la place de 8 n'y
change pas forcement grand chose.
S'il déclare les données dans une struct de quatre octets,
genre :
struct { uint8_t red,green,blue,fill ; } ;
et que le compilateur est assez intelligent pour lire le struct
dans un seul coup, et le tenir dans un régistre, ça dévise le
nombre d'accès par quatre. (Seulement, sur un Intel, les deux
octets de poids fort d'un registre ne sont pas accessible
directement comme octets. Du coup, il faut des décalages et des
masquages, qui ne vont pas accélérer le traitement non plus.)