Tes instructions assembleurs sous-entendent qu'il n'y a pas d'instruction pour incrémenter directement une adresse mémoire (et donc qu'un cpu puisse dire "coucou, j'utilise cette adresse mémoire"). Je n'en suis pas convaincu.
Comment peut tu 'incrémenter directement une adresse mémoire' ?
La ram c'est pas un processeur, tu dois forcément récupérer la mémoire a une adresse un moment , l'incrémenter, puis la remonter en ram.
Déja fait.
Fait le pendant 15h, sur un processeur bien chargé par autre chose (pour forcé des context switch).
Moi aussi déja fait, et les résultats sont bien ce que je dis : non déterministes.
(cf plus bas, vu que je l'ai fait, et en 20 sec j'ai montré ca :D )
Le C ne garantit l'atomicité que pour l'accès et l'écriture (et pas pour tous les types, il n'y a que le type int qui est garantit je crois). Il (la spec du C) ne garantit pas que --n est thread safe.
Comme tu peux le remarquer sur le code asm de ++n sur mon autre commentaire ( https://linuxfr.org/comments/854613.html#854613 )avec un volatile int, ce n'est pas atomique.
et la c'est quand meme gcc 4.1 , donc pas le dernier des compilos codé avec les pieds entre deux cours.
Mais bon faut croire qu'il te faut absolument un exemple alors :
j'ai donc fait un petit programme tout comme il le faut.
Il tourne meme pas sur un quadriporc mais sur un amd 1800+. Donc loin d'etre une foudre de guerre, et uniproc meme pas ht
Voici le code :
volatile int n1;
#define NB_ITER 10000000
void* test4(void * a)
{
long i=NB_ITER;
for (;i>0;--i)
n1++;
}
int main()
{
#define NB_THREAD 50
pthread_t thread[NB_THREAD];
int i=0;
n1=0;
for (;i<NB_THREAD;++i)
{
pthread_create(&thread[i],NULL,test4,NULL);
}
for (i=0;i<NB_THREAD;++i)
{
pthread_join(thread[i],NULL);
}
printf("n = %d =?= %d\n",n1,NB_ITER*NB_THREAD);
}
Comme tu peux le constater, relativement simple. Je lance 50 threads, ils opèrent tous sur n1 qui est défini en globale et volatile.
et ils font chacun une incrémentation avec un opérateur d'après toi 'atomique'
Les tests :
[alpha@oni] /tmp/volatile 20:55:30$ make
gcc -g -o test test.c -lpthread
[alpha@oni] /tmp/volatile 20:55:32$ ./test
n = 295501574 =?= 500000000
[alpha@oni] /tmp/volatile 20:55:37$ ./test
n = 280084287 =?= 500000000
Je te rapelle ce que tu as mis > (d'autant que ton code est pas thread safe, vu que deux personne peuvent rentrer avec ton ++i==1.
Il est thread-safe. J'utilise "volatile". Il est thread-safe à un petit soucis près, ça dépend du compilo et du hardware.Mais sur un PC "classique", ça marche.
Pour faire la meme chose avec un a==1 (ce que tu faisais), c'est plus dur . (Trouver un code qui montre facilement ce probleme).
Toutefois on peut a nouveau regarder le code asm que ca peut nous sortir :
int test3()
{
volatile int a;
if (a==1)
return 0;
return 0;
}
va nous donner :
.globl test3
.type test3, @function
test3:
pushl %ebp
movl %esp, %ebp
subl 20,ドル %esp
movl -4(%ebp), %eax ; on récupère a
cmpl 1,ドル %eax ; on compare a un. On compare pas directement sur -4(%ebp). Donc possibilité de race condition si on change la.
jne .L6
movl 0,ドル -20(%ebp) ; valeur de retour.
jmp .L8
.L6:
movl 0,ドル -20(%ebp)
.L8:
movl -20(%ebp), %eax
leave
ret
.size test3, .-test3
Alors je suis désolé, mais pour moi c'est absolument pas probant.
[^] # Re: Multicoeur ?
Posté par briaeros007 . En réponse à la dépêche Intel libère TBB. Évalué à 3.
Comment peut tu 'incrémenter directement une adresse mémoire' ?
La ram c'est pas un processeur, tu dois forcément récupérer la mémoire a une adresse un moment , l'incrémenter, puis la remonter en ram.
Déja fait.
Fait le pendant 15h, sur un processeur bien chargé par autre chose (pour forcé des context switch).
Moi aussi déja fait, et les résultats sont bien ce que je dis : non déterministes.
(cf plus bas, vu que je l'ai fait, et en 20 sec j'ai montré ca :D )
Le C ne garantit l'atomicité que pour l'accès et l'écriture (et pas pour tous les types, il n'y a que le type int qui est garantit je crois). Il (la spec du C) ne garantit pas que --n est thread safe.
Comme tu peux le remarquer sur le code asm de ++n sur mon autre commentaire ( https://linuxfr.org/comments/854613.html#854613 )avec un volatile int, ce n'est pas atomique.
et la c'est quand meme gcc 4.1 , donc pas le dernier des compilos codé avec les pieds entre deux cours.
Mais bon faut croire qu'il te faut absolument un exemple alors :
j'ai donc fait un petit programme tout comme il le faut.
Il tourne meme pas sur un quadriporc mais sur un amd 1800+. Donc loin d'etre une foudre de guerre, et uniproc meme pas ht
Voici le code :
Comme tu peux le constater, relativement simple. Je lance 50 threads, ils opèrent tous sur n1 qui est défini en globale et volatile.
et ils font chacun une incrémentation avec un opérateur d'après toi 'atomique'
Les tests :
Je te rapelle ce que tu as mis > (d'autant que ton code est pas thread safe, vu que deux personne peuvent rentrer avec ton ++i==1.
Il est thread-safe. J'utilise "volatile". Il est thread-safe à un petit soucis près, ça dépend du compilo et du hardware.Mais sur un PC "classique", ça marche.
Pour faire la meme chose avec un a==1 (ce que tu faisais), c'est plus dur . (Trouver un code qui montre facilement ce probleme).
Toutefois on peut a nouveau regarder le code asm que ca peut nous sortir :
va nous donner :
Alors je suis désolé, mais pour moi c'est absolument pas probant.