Matrix multiplication

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Jan 4 17:48:24 EST 2011


On Tue, 04 Jan 2011 13:22:33 +0100, Zdenko wrote:

> I wrote these two codes for example:
> 
> this one is naive way of matrix multiplication using one thread
[...]
> this one is using two threads, each one is multiplying half of matrix
[...]
> why is second one more than twice slower than first when it should be
> faster. I suspect that problem is in simultaneous access to matrix C but
> i don't know how to solve this.

Can I suggest that your timing code leaves something to be desired?

* You time too much. You're interested in how long it takes to multiply 
two matrices, but you time how long it takes to do much more than just 
the multiplication: your timing code covers the time it takes to create 
the class object (which will be trivial), and build the matrix (non-
trivial), as well as perform the multiplication.

* Your perform the timing test once, which makes it subject to sampling 
errors. (Although if the process takes a long time, say, multiple 
seconds, the sampling error will *probably* be small relative to the 
measured time. But not always.)

* You use time.clock, but without knowing which operating system you are 
running, it's impossible to tell whether you should be using time.time 
instead.

Whether these issues will actually make a practical difference in this 
*specific* case, I don't know, but as a general rule, the most accurate 
way to perform these sorts of timing tests is with the timeit module. 
Something like this:


A = ... # initialise matrix A
B = ... # and B
C = ... # and the result

def mult1(A, B, C):
    # Multiply matrices A and B using 1 thread.
    t = MyThread()
    t.start()
    t.join()

def mult2(A, B, C):
    # Multiply matrices A and B using 2 threads.
    t1 = MyThread()
    t2 = MyThread()
    t1.start()
    t2.start()
    t1.join()  # Block until thread 1 is done.
    t2.join()  # Now block until thread 2 is done.

setup1 = "from __main__ import A, B, C, mult1"
setup2 = "from __main__ import A, B, C, mult2"

from timeit import Timer
t1 = Timer("mult1(A, B, C)", setup1)
t2 = Timer("mult2(A, B, C)", setup2)


# Now perform the timing tests.
best1 = min(t1.repeat())
best2 = min(t2.repeat())

By default, Timer.repeat will measure the time taken by one million 
iterations of the code snippet, and take three measurements. You almost 
always only care about the smallest measurement -- any larger times will 
represent sampling error.

If it takes too long to time one million iterations, either make the 
matrices smaller, or pass keyword arguments number and/or repeat to the 
repeat method:

# best of five measurements of one hundred iterations
best1 = min(t1.repeat(number=100, repeat=5))



-- 
Steven



More information about the Python-list mailing list