Python code to benchmark in flops using threading

969 Views Asked by At

I'm having trouble writing a benchmark code in python using threading. I was able to get my threading to work, but I can't get my object to return a value. I want to take the values and add them to a list so I can calculate the flops.

create class to carry out threading

class myThread(threading.Thread):

    def calculation(self):
        n=0
        start=time.time()
        ex_time=0
        while ex_time < 30:
            n+=1
            end=time.time()
            ex_time=end-start
        return ex_time 


    def run(self): 
        t = threading.Thread(target = self.calculation)
        t.start()

function to create threads

def make_threads(num):
    times=[]
    calcs=[]
    for i in range(num):
        print('start thread', i+1)
        thread1=myThread()
        t=thread1.start()
        times.append(t)
     #calcs.append(n)
    #when trying to get a return value it comes back as none as seen
    print(times)
#average out the times,add all the calculations to get the final numbers
#to calculate flops
    time.sleep(32) #stop the menu from printing until calc finish


def main():

    answer=1
    while answer != 0:
        answer=int(input("Please indicate how many threads to use: (Enter     0 to exit)"))
        print("\n\nBenchmark test with ", answer, "threads")
        make_threads(answer)

main()
1

There are 1 best solutions below

2
On

Two ways to do this:

1. Using static variables (hacky, but efficient and quick)

Define some global variable that you then manipulate in the thread. I.e.:

import threading
import time

class myThread(threading.Thread):

    def calculation(self):
        n=0
        start=time.time()
        ex_time=0
        print("Running....")
        while ex_time < 30:
            n+=1
            end=time.time()
            ex_time=end-start

        self.myThreadValues[self.idValue] = ex_time
        print(self.myThreadValues)
        return ex_time 

    def setup(self,myThreadValues=None,idValue=None):
        self.myThreadValues = myThreadValues
        self.idValue = idValue


    def run(self): 
        self.calculation()
        #t = threading.Thread(target = self.calculation)
        #t.start()

def make_threads(num):
    threads=[]
    calcs=[]
    myThreadValues = {}

    for i in range(num):
        print('start thread', i+1)
        myThreadValues[i] = 0
        thread1=myThread()
        thread1.setup(myThreadValues,i)
        thread1.start()
        #times.append(t)
        threads.append(thread1)

    # Now we need to wait for all the threads to finish. There are a couple ways to do this, but the best is joining.

    print("joining all threads...")
    for thread in threads:
        thread.join()

    #calcs.append(n)
    #when trying to get a return value it comes back as none as seen

    print("Final thread values: " + str(myThreadValues))
    print("Done")
    #average out the times,add all the calculations to get the final numbers
    #to calculate flops
    #time.sleep(32) #stop the menu from printing until calc finish

def main():

    answer=1
    while answer != 0:
        answer=int(input("Please indicate how many threads to use: (Enter     0 to exit)"))
        print("\n\nBenchmark test with ", answer, "threads")
        make_threads(answer)

main()

2. The proper way to do this is with Processes

Processes are designed for passing information back and forth, versus threads which are commonly used for async work. See explanation here: https://docs.python.org/3/library/multiprocessing.html

See this answer: How can I recover the return value of a function passed to multiprocessing.Process?

import multiprocessing
from os import getpid

def worker(procnum):
    print 'I am number %d in process %d' % (procnum, getpid())
    return getpid()

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes = 3)
    print pool.map(worker, range(5))