Questo comportamento è del tutto ragionevole, vediamo cosa succede.
loop seriale
In ogni iterazione che stai ricevendo uno A
che viene creato sul mucchio, e uno è sempre distrutta. Queste operazioni sono ordinate in questo modo:
- costruzione
- distruzione
- costruzione
- distruzione
- ... (e così via) sono stati creati
Dal momento che i A
s sull'heap, passano attraverso l'allocatore di memoria. Quando l'allocatore di memoria riceve una richiesta di nuova memoria come nel passaggio 3, in molti casi (in molti casi) guarderà prima alla memoria liberata di recente. Vede che l'ultima operazione era una memoria priva della giusta misura (passo 2), e quindi prenderà di nuovo quel pezzo di memoria. Questa procedura verrà ripetuta in ogni iterazione. Quindi il ciclo seriale (comunemente ma non necessariamente) fornirà lo stesso indirizzo più e più volte.
loop parallelo
Ora pensiamo al ciclo parallelo. Poiché non c'è sincronizzazione, l'ordinamento delle allocazioni e delle allocazioni di memoria non è determinato. Pertanto è possibile che siano interfogliati in qualunque modo tu possa immaginare. Quindi, in generale, l'allocatore di memoria non sarà in grado di utilizzare lo stesso trucco dell'ultima volta per distribuire sempre lo stesso pezzo di memoria.Un esempio ordinamento può essere per esempio che tutti e quattro A
s vengono costruiti prima che tutti distrutti - qualcosa di simile:
- costruzione
- costruzione
- costruzione
- costruzione
- distruzione
- distruzione
- distruzione
- distruzione
L'allocatore di memoria dovrà pertanto servire fino 4 nuovi pezzi della memoria prima di poter ottenere un certo indietro e ricominciare il riciclaggio.
Il comportamento della versione basata su stack è leggermente più deterministico, ma può dipendere dalle ottimizzazioni del compilatore. Per la versione seriale ogni volta che l'oggetto viene creato/distrutto viene regolato il puntatore dello stack. Dato che non c'è nulla in mezzo, continuerà a essere creato nella stessa posizione.
Per la versione parallela, ogni thread ha il proprio stack in un sistema di memoria condivisa. Pertanto ogni thread creerà i suoi oggetti in una diversa posizione di memoria, e non è possibile alcun "riciclo".
Il comportamento che stai vedendo non è in alcun modo strano o comunque garantito. Dipende dalla quantità di core fisici che hai, da quanti thread vengono eseguiti, da quante iterazioni usi - generalmente le condizioni di runtime.
Riga inferiore: tutto va bene, non dovresti leggerlo troppo.
un downvote di 5 secondi dopo la pubblicazione? perché ? – PinkFloyd