Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
// Target a specific processor for the thread to run on
public class ThreadProcessor
{
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentThread();
[DllImport("kernel32.dll")]
private static extern IntPtr SetThreadAffinityMask(IntPtr hThread, IntPtr dwThreadAffinityMask);
public static void Usage()
{
int cpu = 0;
ThreadProcessor tp = new ThreadProcessor();
Console.WriteLine("Spike CPU 1");
tp.SpikeCPU(cpu);
if (tp._ex != null)
{
Console.WriteLine(tp._ex.Message);
}
else
{
if (Environment.ProcessorCount > 1)
{
while (++cpu < Environment.ProcessorCount)
{
Thread.Sleep(1000);
Console.WriteLine("Spike CPU " + (cpu + 1).ToString());
tp.SpikeCPU(cpu);
if (tp._ex != null)
{
Console.WriteLine(tp._ex.Message);
break;
}
}
}
else // Either a single CPU or hyperthreading not enabled in the OS or the BIOS.
{
Console.WriteLine("This PC does not have two processors available.");
}
}
}
private Thread _worker;
private const int PiSignificantDigits = 750; // Adjust to your processor
// Spike the CPU and waith for it to finish
public void SpikeCPU(int targetCPU)
{
// Create a worker thread for the work.
_worker = new Thread(DoBusyWork); // Background is set so not to not prevent the
// mainprocess from terminating if someone closes it.
_worker.IsBackground = true;
_worker.Start((object) targetCPU);
_worker.Join(); // Wait for it to be done.
}
public void DoBusyWork(object target)
{
try
{
int processor = (int) target;
Thread tr = Thread.CurrentThread;
if (Environment.ProcessorCount > 1)
{
SetThreadAffinityMask(GetCurrentThread(), new IntPtr(1 << processor));
}
CalculatePI.Process(PiSignificantDigits);
}
catch (Exception ex)
{
_ex = ex;
}
}
public Exception _ex = null;
}
// Source:
// http://omegacoder.com/?p=91
public class CalculatePI
{
/*
Computation of the n'th decimal digit of \pi with very little memory.
Written by Fabrice Bellard on January 8, 1997.
We use a slightly modified version of the method described by Simon
Plouffe in "On the Computation of the n'th decimal digit of various
transcendental numbers" (November 1996). We have modified the algorithm
to get a running time of O(n^2) instead of O(n^3log(n)^3).
This program uses mostly integer arithmetic. It may be slow on some
hardware where integer multiplications and divisions must be done
by software. We have supposed that 'int' has a size of 32 bits. If
your compiler supports 'long long' integers of 64 bits, you may use
the integer version of 'mul_mod' (see HAS_LONG_LONG).
Call this static to use.
*/
public static string Process(int digits)
{
StringBuilder result = new StringBuilder();
result.Append("3.");
DateTime StartTime = DateTime.Now;
if (digits > 0)
{
for (int i = 0; i < digits; i += 9)
{
String ds = CalculatePiDigits(i + 1);
int digitCount = Math.Min(digits - i, 9);
if (ds.Length < 9)
ds = string.Format("{0:D9}", int.Parse(ds));
result.Append(ds.Substring(0, digitCount));
}
}
return result.ToString();
}
private static int mul_mod(int a, int b, int m)
{
return (int) (((long) a * (long) b) % m);
}
/* return the inverse of x mod y */
private static int inv_mod(int x, int y)
{
int q, u, v, a, c, t;
u = x;
v = y;
c = 1;
a = 0;
do
{
q = v / u;
t = c;
c = a - q * c;
a = t;
t = u;
u = v - q * u;
v = t;
} while (u != 0);
a = a % y;
if (a < 0)
{
a = y + a;
}
return a;
}
/* return (a^b) mod m */
private static int pow_mod(int a, int b, int m)
{
int r, aa;
r = 1;
aa = a;
while (true)
{
if ((b & 1) != 0)
{
r = mul_mod(r, aa, m);
}
b = b >> 1;
if (b == 0)
{
break;
}
aa = mul_mod(aa, aa, m);
}
return r;
}
/* return true if n is prime */
private static bool is_prime(int n)
{
if ((n % 2) == 0)
{
return false;
}
int r = (int) Math.Sqrt(n);
for (int i = 3; i <= r; i += 2)
{
if ((n % i) == 0)
{
return false;
}
}
return true;
}
/* return the prime number immediatly after n */
private static int next_prime(int n)
{
do
{
n++;
} while (!is_prime(n));
return n;
}
private static String CalculatePiDigits(int n)
{
int av, vmax, num, den, s, t;
int N = (int) ((n + 20) * Math.Log(10) / Math.Log(2));
double sum = 0;
for (int a = 3; a <= (2 * N); a = next_prime(a))
{
vmax = (int) (Math.Log(2 * N) / Math.Log(a));
av = 1;
for (int i = 0; i < vmax; i++)
{
av = av * a;
}
s = 0;
num = 1;
den = 1;
int v = 0;
int kq = 1;
int kq2 = 1;
for (int k = 1; k <= N; k++)
{
t = k;
if (kq >= a)
{
do
{
t = t / a;
v--;
} while ((t % a) == 0);
kq = 0;
}
kq++;
num = mul_mod(num, t, av);
t = 2 * k - 1;
if (kq2 >= a)
{
if (kq2 == a)
{
do
{
t = t / a;
v++;
} while ((t % a) == 0);
}
kq2 -= a;
}
den = mul_mod(den, t, av);
kq2 += 2;
if (v > 0)
{
t = inv_mod(den, av);
t = mul_mod(t, num, av);
t = mul_mod(t, k, av);
for (int i = v; i < vmax; i++)
{
t = mul_mod(t, a, av);
}
s += t;
if (s >= av)
{
s -= av;
}
}
}
t = pow_mod(10, n - 1, av);
s = mul_mod(s, t, av);
sum = (sum + (double) s / (double) av) % 1.0;
}
int Result = (int) (sum * 1e9);
String StringResult = String.Format("{0:D9}", Result);
return StringResult;
}
// Put a space between every group of 10 digits.
private static String breakDigitsIntoGroupsOf10(String digits)
{
String result = "";
while (digits.Length > 10)
{
result += digits.Substring(0, 10) + " ";
digits = digits.Substring(10, digits.Length - 10);
}
result += digits;
return result;
}
}
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Threading
' Target a specific processor for the thread to run on
Public Class ThreadProcessor
<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentThread() As IntPtr
End Function
<DllImport("kernel32.dll")> _
Private Shared Function SetThreadAffinityMask(hThread As IntPtr, dwThreadAffinityMask As IntPtr) As IntPtr
End Function
Public Shared Sub Usage()
Dim cpu As Integer = 0
Dim tp As New ThreadProcessor()
Console.WriteLine("Spike CPU 1")
tp.SpikeCPU(cpu)
If tp._ex IsNot Nothing Then
Console.WriteLine(tp._ex.Message)
Else
If Environment.ProcessorCount > 1 Then
While System.Threading.Interlocked.Increment(cpu) < Environment.ProcessorCount
Thread.Sleep(1000)
Console.WriteLine("Spike CPU " & (cpu + 1).ToString())
tp.SpikeCPU(cpu)
If tp._ex IsNot Nothing Then
Console.WriteLine(tp._ex.Message)
Exit While
End If
End While
Else
' Either a single CPU or hyperthreading not enabled in the OS or the BIOS.
Console.WriteLine("This PC does not have two processors available.")
End If
End If
End Sub
Private _worker As Thread
Private Const PiSignificantDigits As Integer = 750
' Adjust to your processor
' Spike the CPU and waith for it to finish
Public Sub SpikeCPU(targetCPU As Integer)
' Create a worker thread for the work.
_worker = New Thread(AddressOf DoBusyWork)
' Background is set so not to not prevent the
' mainprocess from terminating if someone closes it.
_worker.IsBackground = True
_worker.Start(DirectCast(targetCPU, Object))
_worker.Join()
' Wait for it to be done.
End Sub
Public Sub DoBusyWork(target As Object)
Try
Dim processor As Integer = CInt(target)
Dim tr As Thread = Thread.CurrentThread
If Environment.ProcessorCount > 1 Then
SetThreadAffinityMask(GetCurrentThread(), New IntPtr(1 << processor))
End If
CalculatePI.Process(PiSignificantDigits)
Catch ex As Exception
_ex = ex
End Try
End Sub
Public _ex As Exception = Nothing
End Class
' Source:
' http://omegacoder.com/?p=91
Public Class CalculatePI
' Computation of the n'th decimal digit of \pi with very little memory.
' Written by Fabrice Bellard on January 8, 1997.
' We use a slightly modified version of the method described by Simon
' Plouffe in "On the Computation of the n'th decimal digit of various
' transcendental numbers" (November 1996). We have modified the algorithm
' to get a running time of O(n^2) instead of O(n^3log(n)^3).
'
' This program uses mostly integer arithmetic. It may be slow on some
' hardware where integer multiplications and divisions must be done
' by software. We have supposed that 'int' has a size of 32 bits. If
' your compiler supports 'long long' integers of 64 bits, you may use
' the integer version of 'mul_mod' (see HAS_LONG_LONG).
'
' Call this static to use.
Public Shared Function Process(digits As Integer) As String
Dim result As New StringBuilder()
result.Append("3.")
Dim StartTime As DateTime = DateTime.Now
If digits > 0 Then
For i As Integer = 0 To digits - 1 Step 9
Dim ds As String = CalculatePiDigits(i + 1)
Dim digitCount As Integer = Math.Min(digits - i, 9)
If ds.Length < 9 Then
ds = String.Format("{0:D9}", Integer.Parse(ds))
End If
result.Append(ds.Substring(0, digitCount))
Next
End If
Return result.ToString()
End Function
Private Shared Function mul_mod(a As Integer, b As Integer, m As Integer) As Integer
Return CInt((CLng(a) * CLng(b)) Mod m)
End Function
' return the inverse of x mod y
Private Shared Function inv_mod(x As Integer, y As Integer) As Integer
Dim q As Integer, u As Integer, v As Integer, a As Integer, c As Integer, t As Integer
u = x
v = y
c = 1
a = 0
Do
q = v \ u
t = c
c = a - q * c
a = t
t = u
u = v - q * u
v = t
Loop While u <> 0
a = a Mod y
If a < 0 Then
a = y + a
End If
Return a
End Function
' return (a^b) mod m
Private Shared Function pow_mod(a As Integer, b As Integer, m As Integer) As Integer
Dim r As Integer, aa As Integer
r = 1
aa = a
While True
If (b And 1) <> 0 Then
r = mul_mod(r, aa, m)
End If
b = b >> 1
If b = 0 Then
Exit While
End If
aa = mul_mod(aa, aa, m)
End While
Return r
End Function
' return true if n is prime
Private Shared Function is_prime(n As Integer) As Boolean
If (n Mod 2) = 0 Then
Return False
End If
Dim r As Integer = CInt(Math.Truncate(Math.Sqrt(n)))
For i As Integer = 3 To r Step 2
If (n Mod i) = 0 Then
Return False
End If
Next
Return True
End Function
' return the prime number immediatly after n
Private Shared Function next_prime(n As Integer) As Integer
Do
n += 1
Loop While Not is_prime(n)
Return n
End Function
Private Shared Function CalculatePiDigits(n__1 As Integer) As String
Dim av As Integer, vmax As Integer, num As Integer, den As Integer, s As Integer, t As Integer
Dim N__2 As Integer = CInt(Math.Truncate((n__1 + 20) * Math.Log(10) / Math.Log(2)))
Dim sum As Double = 0
Dim a As Integer = 3
While a <= (2 * N__2)
vmax = CInt(Math.Truncate(Math.Log(2 * N__2) / Math.Log(a)))
av = 1
For i As Integer = 0 To vmax - 1
av = av * a
Next
s = 0
num = 1
den = 1
Dim v As Integer = 0
Dim kq As Integer = 1
Dim kq2 As Integer = 1
For k As Integer = 1 To N__2
t = k
If kq >= a Then
Do
t = t \ a
v -= 1
Loop While (t Mod a) = 0
kq = 0
End If
kq += 1
num = mul_mod(num, t, av)
t = 2 * k - 1
If kq2 >= a Then
If kq2 = a Then
Do
t = t \ a
v += 1
Loop While (t Mod a) = 0
End If
kq2 -= a
End If
den = mul_mod(den, t, av)
kq2 += 2
If v > 0 Then
t = inv_mod(den, av)
t = mul_mod(t, num, av)
t = mul_mod(t, k, av)
For i As Integer = v To vmax - 1
t = mul_mod(t, a, av)
Next
s += t
If s >= av Then
s -= av
End If
End If
Next
t = pow_mod(10, n__1 - 1, av)
s = mul_mod(s, t, av)
sum = (sum + CDbl(s) / CDbl(av)) Mod 1.0
a = next_prime(a)
End While
Dim Result As Integer = CInt(Math.Truncate(sum * 1000000000.0))
Dim StringResult As String = String.Format("{0:D9}", Result)
Return StringResult
End Function
' Put a space between every group of 10 digits.
Private Shared Function breakDigitsIntoGroupsOf10(digits As String) As String
Dim result As String = ""
While digits.Length > 10
result += digits.Substring(0, 10) & " "
digits = digits.Substring(10, digits.Length - 10)
End While
result += digits
Return result
End Function
End Class
If you are experiencing a similar issue, please ask a related question
Join the community of 500,000 technology professionals and ask your questions.