This little block of code will is used in a console app to test throuput on threads.

TOTAL can be equal to 1 to 64

Try 9 threads on an 8 core machine, seven run at the same speed, and two run at one-half

Try 4 threads then 5 threads.... the scaling is exactly linear right from 1 to 8


Imports System
Imports System.Threading
Imports System.Threading.Tasks

Module Module12
    Private TOTAL As Integer = 8 - 1   'array size = number of threads starting a zero (ex. 8-1 = 8threads)
    Private ClassThreadHolders(TOTAL) As LoopThread 'array of classes
    Private ThreadArray(TOTAL) As Thread      'array of threads
    Private TotalAccumIncs As Long
    Private AccumIncs As Integer

    Sub Main()
        Dim n As Integer = 0                  'local loop var used in fors
        Dim ThreadPrintLoop As New Thread(AddressOf PrintLoop)

        Console.WriteLine("Building threads...")
        For n = 0 To TOTAL                                      'for each thread
            ClassThreadHolders(n) = New LoopThread                            'assign the class
            ThreadArray(n) = New Thread(AddressOf ClassThreadHolders(n).ActualThread) 'assign the pointer to the thread function

        Console.WriteLine("starting threads...")
        For n = 0 To TOTAL          'for each thread
            ThreadArray(n).Start()          'start the thread

        Console.WriteLine("Starting Printloop...")
        ThreadPrintLoop.Start()                'start printing thread

        Console.WriteLine("Waiting for keypress...")
        Console.ReadKey()                       'wait for key
        End                                     'orderly shutdown
    End Sub

    Private Sub PrintLoop()    'thread to print data on
        Do                      'infinite loop of thread
            Thread.Sleep(1000)    'sleep 1000 = 1 sec delay
            For j As Integer = 0 To TOTAL      'for each thread
                ClassThreadHolders(j).Grab()    'force the grab
            TotalAccumIncs = 0

            For j As Integer = 0 To TOTAL
                AccumIncs = ClassThreadHolders(j).GetGrabbed
                TotalAccumIncs += AccumIncs
                Console.Write(Format(AccumIncs, "000,000,000,000     "))
            Console.Write(vbCrLf + Format(TotalAccumIncs, "000,000,000,000     "))
    End Sub

    Public Class LoopThread         'need a class to have a pointer to a function that can be arrayed
        Private GrabbedInc As Integer
        Private Inc As Integer = 1    'class var must be fully declared
        Private GrabFlag As Boolean
        Private num As Double = 10
        Private num2 As Double = 5

        Public Sub ActualThread()         'sub on the thread
            Do                              'infinite loop of thread
                If GrabFlag = True Then
                    GrabFlag = False
                    GrabbedInc = Inc
                    Inc = 0
                End If
                'num = num * num2 / 50
                Inc += 1
        End Sub

        Sub Grab()
            GrabFlag = True
        End Sub

        Public ReadOnly Property GetGrabbed() As Integer
                Return GrabbedInc
            End Get
        End Property

    End Class

End Module