Witam,
od kilku dni próbuję dojść do tego jak usprawnić działanie metody Sito Eratostenesa, w celu jak najszybszego wykonania na wielu wątkach aplikacji. Prawidłowy wynik podobny do tego w aplikacji wykorzystującej jeden wątek otrzymuję jedynie po zastosowaniu Thread.Sleep i Lock. Taka forma mimo iż jest bardziej wydajna dla większych liczb wydaje mi się nieelegancka, czy da się jakoś usprawnić synchronizację w tej metodzie? W button1 zawarta jest metoda działająca na jednym wątku a w button2 na wielu.
public partial class Form1 : Form
{
Stopwatch sw = new Stopwatch();
List<Thread> lt;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int n = Convert.ToInt32(textBox1.Text);
bool[] tab = new bool[n + 1];
sw.Reset();
sw.Start();
for (int i = 2; i * i <= n; i++)
{
if (tab[i] == true)
{
continue;
}
for (int j = 2 * i; j <= n; j += i)
{
tab[j] = true;
}
}
sw.Stop();
WypiszWynik(n, tab);
}
private void button2_Click(object sender, EventArgs e)
{
int n = Convert.ToInt32(textBox1.Text);
bool[] tab = new bool[n + 1];
lt = new List<Thread>();
sw.Reset();
sw.Start();
for (int i = 2; i * i <= n; i++)
{
if (tab[i] == true)
{
continue;
}
lt.Add(new Thread(() => Eliminacja(i, n, tab)));
lt.Last().Start();
lock (tab)
{
Thread.Sleep(1);
}
}
foreach (var t in lt)
{
t.Join();
}
sw.Stop();
WypiszWynik(n, tab);
}
private void Eliminacja(int i, int n, bool[] tab)
{
for (int j = 2 * i; j <= n; j += i)
{
tab[j] = true;
}
}
private void WypiszWynik(int n, bool[] tab)
{
long suma = 0;
listBox1.Items.Clear();
listBox1.Items.Add("Liczby pierwsze z zakresu [0," + n + "]: ");
for (int i = 2; i <= n; i++)
{
if (tab[i] == false)
{
if (n < 1000)
{
listBox1.Items.Add(i + " ");
}
suma += i;
}
}
listBox1.Items.Add("Suma: " + suma);
listBox1.Items.Add("Czas operacji: " + sw.ElapsedMilliseconds);
}
}