For build 3 of DoubleMark i once again revised the algorithm. I completely eliminated floating points and operations and so on, however i am baffled as to what i have done wrong with multi-threading the algorithm. I will include complete documentation to speed up any help given, since the algorithm is hard to read (so i've been told, since i wrote it my opinion doesn't count.)

When the button is pressed :

The thread management code (executed in a different thread to prevent GUI hangs) :

And the single-core algorithm, which is flawless :

And the multi-threaded algorithm :

I hate to ask such a large task of anyone but i have delayed the third build of DoubleMark very long over this issue and i cannot resolve it it seams. Someone more experienced will probably point out some stupid mistake but i'd be happy to have it working.

If you need to know anything else or are interested i provide the following links.

OverClock.Net DoubleMark Topic

OverClock.Net DoubleMark Blog

When the button is pressed :

Code:

```
private void button1_Click(object sender, EventArgs e) //Benchmark Button
{
textBox1.Text += System.Environment.NewLine;
if (checkBox1.Checked == true)
{
Thread Thread1 = new Thread(PrimeNumbers);
Thread1.Start(1);
}
else
{
for (int i = 0; i < Environment.ProcessorCount; i++)
{
threads[i] = new Thread(PrimeNumbers);
threads[i].Start(i + 1);
PNumbers[i] = 0;
textBox1.Text += System.Environment.NewLine + "Thread #" + Convert.ToString(i)
+ System.Environment.NewLine + " has started." + System.Environment.NewLine;
}
Thread endrun = new Thread(threadwait);
endrun.Start();
}
button1.Enabled = false;
}
```

Code:

```
private void threadwait()
{
for (int i = 0; i < Environment.ProcessorCount; i++)
{
if (threads[i].IsAlive == true)
{
threads[i].Join();
}
}
int TotalPNumber = 0;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
TotalPNumber += PNumbers[i];
}
MessageBox.Show("Test Complete; Prime Numbers Found : " + Convert.ToString(TotalPNumber + 4) + "; Time Taken : ");
button1.Enabled = true;
}
```

Code:

```
private void PrimeNumbers(object threadnumber)
{
if (checkBox1.Checked == true)//Single
{
foreach (ProcessThread pt in Process.GetCurrentProcess().Threads)
{
int utid = GetCurrentThreadId();
if (utid == pt.Id)
{
pt.ProcessorAffinity = (IntPtr)(Convert.ToInt32(threadnumber));
}
}
int FNumber = 11;
int PNumber = 4;
int SNumber = 3;
int TNumber = Convert.ToInt32(TestLength * 0.1 - 10);
for (int i = 0; i < TNumber; i++)
{
for (int u = 0; u < (FNumber * 0.25); u++) // 1
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 2;
for (int u = 0; u < (FNumber * 0.25); u++) // 3
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 4;
for (int u = 0; u < (FNumber * 0.25); u++) // 7
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 2;
for (int u = 0; u < (FNumber * 0.25); u++) // 9
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 2;
progressBar1.Value = (FNumber / TestLength * 100);
}
progressBar1.Value = 100;
MessageBox.Show("Test Complete; Prime Numbers Found : " + Convert.ToString(PNumber));
progressBar1.Value = 0;
button1.Enabled = true;
}
}
```

**[If you see #region or #endregion thats for orginization and is not part of the actual code.**And the multi-threaded algorithm :

Code:

```
else
{
int FNumber = Convert.ToInt32(threadnumber) + 1 * 10 + 1;
int PNumber = 0;
int SNumber = 3;
int TNumber = Convert.ToInt32(TestLength * 0.1 / Environment.ProcessorCount); //since the algorithm checks in groups of 10 with 4 numbers from each group divide (or in this case multiply by 0.1) the number to be checked by ten then by the number of threads and you have how many iterations each thread will need
for (int i = 0; i < TNumber; i++)
{
for (int u = 0; u < (FNumber * 0.25); u++) // 1
{
if (FNumber % SNumber == 0) //it is simple, if theres no remainder is not a prime number, however if the loop reaches its end with all remainders then that means the number has no other number that can be equally divided into it and it is a prime number (also, in the case the rainder isn't 0 and the loop is continueing it increases the divisor)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 2;
for (int u = 0; u < (FNumber * 0.25); u++) // 3
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 4;
for (int u = 0; u < (FNumber * 0.25); u++) // 7
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += 2;
for (int u = 0; u < (FNumber * 0.25); u++) // 9
{
if (FNumber % SNumber == 0)
{
PNumber -= 1;
break;
}
else
{
SNumber += 2;
}
}
PNumber += 1;
SNumber = 3;
FNumber += Environment.ProcessorCount * 10 + 2; //+2 will increase the 10s place by 1, thus you only need 10 times the processor count plus 2 to acheive the desired effect of each getting its own set of 10s each iteration
progressBar1.Value = (FNumber / TestLength * 100);
}
PNumbers[Convert.ToInt32(threadnumber) - 1] = PNumber; //Prevents crossthread data access corruption
}
```

If you need to know anything else or are interested i provide the following links.

OverClock.Net DoubleMark Topic

OverClock.Net DoubleMark Blog