Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2016
    Messaggi
    89

    C# Parallel.For da valori sbagliati se lavoro con numeri elevati...

    codice:
    int n = 100000, a = 0;
    Parallel.For(0, n, i =>
    {
       a++;
    });
    Console.WriteLine(a);
    il problema è che mi stampa a sempre con un valore diverso, ho notato che se assegno ad n numeri bassi come per esempio 10,100 ottengo la stampa di a corretta ma se asseno ad n numeri elevati come nell'esempio ottengo numeri sballati... è possibile risolvere questo errore? sbaglio qualcosa?

  2. #2
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    C'è un problema di concorrenza: l'incremento è diviso in due fasi, incremento e assegnazione, se avviene una sospensione fra le due l'incremento avviene per più thread diversi sul valore precedente. Avrai notato che i valori sono sempre minori dell'atteso.
    Per risolvere problemi semplici come questo puoi usare i metodi Interlocked.
    Più in generale dovresti informarti su concurrency e multithreading.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  3. #3
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    Proa a usare linqcn imetodo asordered

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2016
    Messaggi
    89
    codice:
    int n =100000, a =0;
    Parallel.For(0, n, i =>
    {
      a = Interlocked.Add(a,1);
    });
    Console.WriteLine(a);
    Non ho avuto tempo di provarlo ma credo vada scritto così...
    il problema e che nell'esempio ho messo una variabile int ma se volessi usare una variabile BigInteger, Interlocked non funzionerebbe perchè Interlocked.Add accetta variabili int...

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2015
    Messaggi
    57
    Interlocked esegue anche la sommatoria per le variabili long
    https://msdn.microsoft.com/it-it/lib...v=vs.110).aspx

    comunque, il sistema come descritto � inutile,
    calcolando lo speedup ti accorgerai subito come sia conveniente, in questo caso, una soluzione di tipo sequenziale

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2016
    Messaggi
    89
    ho provato ad usare
    Interlocked.Add(BigInteger, BigInteger);ma ottengo un errore perch� io non ho bisogno di usare una variabile long ma ho bisogno di usare una variabile BigInteger...

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2016
    Messaggi
    89
    scusa la mia ignoranza, cosa intendi per "soluzione sequenziale"?

  8. #8
    Utente di HTML.it
    Registrato dal
    Jul 2015
    Messaggi
    57
    esistono parecchi sistemi per la protezione delle risorse in contesti unsafe,

    potresti utilizzare le funzioni primitive di lock ad esempio
    https://msdn.microsoft.com/it-it/library/c5kehkcz.aspx

    codice:
     
    object locker = new object();
    int n = 10000000;
    BigInteger bigInteger = 0;
                
    Parallel.For(0, n, i =>
    {
     lock (locker)
     {
      bigInteger++;
     }
    });
    
    la vera domanda da porsi è, ha senso eseguire un codice del genere?

    il parallelismo e la concorrenza dovrebbero prevedere il fatto che più porzioni di codice
    vengono eseguite nello stesso tempo

    se togli questo, rimane solo overhead
    Ultima modifica di Marsh; 18-01-2017 a 12:37

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2016
    Messaggi
    89
    ok grazie mille

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.