Ho un'applicazione che richiede un uso intensivo della CPU. Quando i dati vengono elaborati su un singolo thread, l'utilizzo della CPU passa al 100% per molti minuti. Quindi le prestazioni dell'applicazione sembrano essere vincolate dalla CPU. Ho multithreading la logica dell'applicazione, che si traducono in un aumento delle prestazioni complessive. Tuttavia, l'utilizzo della CPU difficilmente supera il 30% -50%. Mi aspetto che la CPU (e molti core) vada al 100% dal momento che elaboro molti set di dati allo stesso tempo.Quali sono i motivi per cui l'utilizzo della CPU non va al 100% con C# e APM?
Di seguito è riportato un esempio semplificato della logica che utilizzo per avviare i thread. Quando eseguo questo esempio, la CPU va al 100% (su una macchina 8/16 core). Tuttavia, la mia applicazione che utilizza lo stesso modello non lo fa.
public class DataExecutionContext
{
public int Counter { get; set; }
// Arrays of data
}
static void Main(string[] args)
{
// Load data from the database into the context
var contexts = new List<DataExecutionContext>(100);
for (int i = 0; i < 100; i++)
{
contexts.Add(new DataExecutionContext());
}
// Data loaded. Start to process.
var latch = new CountdownEvent(contexts.Count);
var processData = new Action<DataExecutionContext>(c =>
{
// The thread doesn't access data from a DB, file,
// network, etc. It reads and write data in RAM only
// (in its context).
for (int i = 0; i < 100000000; i++)
c.Counter++;
});
foreach (var context in contexts)
{
processData.BeginInvoke(context, new AsyncCallback(ar =>
{
latch.Signal();
}), null);
}
latch.Wait();
}
Ho ridotto il numero di blocchi al minimo (solo il blocco è bloccato). Il modo migliore che ho trovato è stato quello di creare un contesto in cui un thread può leggere/scrivere in memoria. I contesti non sono condivisi tra altri thread. I thread non possono accedere al database, ai file o alla rete. In altre parole, ho profilato la mia domanda e non ho trovato alcun collo di bottiglia.
Perché l'utilizzo della CPU della mia applicazione non aumenta del 50%? È lo schema che uso? Dovrei creare il mio thread invece di usare il pool di thread .Net? C'è qualche trucchetto? C'è qualche strumento che potresti raccomandarmi per trovare il mio problema?
Grazie!
Possibile, ma poco probabile sarebbe che il codice sta provocando un sacco di garbage collection, che richiede una certa quantità di sincronizzazione. –