You think that's a speedup? :P
You're only using of the multiprocessors in your GPU! (Because you're launching
a 1x1 grid). Try this on for size:
======
import pycuda.driver as drv
import pycuda.tools
import pycuda.autoinit
import numpy
import numpy.linalg as la
from pycuda.compiler import SourceModule
blocks = 64
block_size = 128
nbr_values = blocks * block_size
n_iter = 100000
#############
# GPU SECTION
mod = SourceModule("""
__global__ void addone(float *dest, float *a, int n_iter)
{
const int i = blockDim.x*blockIdx.x + threadIdx.x;
for(int n = 0; n < n_iter; n++) {
a[i] = sin(a[i]);
}
dest[i] = a[i];
}
""")
addone = mod.get_function("addone")
a = numpy.ones(nbr_values).astype(numpy.float32)
a += 1 # a is now an array of 2s
dest = numpy.zeros_like(a)
start = drv.Event()
end = drv.Event()
start.record()
addone(drv.Out(dest), drv.In(a), numpy.int32(n_iter), grid=(blocks,1),
block=(block_size,1,1))
#stop timer
end.record()
end.synchronize()
secs = start.time_till(end)*1e-3
print "GPU time:", secs
print "GPU result starts with...", dest[:3]
#############
# CPU SECTION
a = numpy.ones(nbr_values).astype(numpy.float32)
a += 1 # a is now an array of 2s
start.record()
for i in range(n_iter):
a = numpy.sin(a)
#stop timer
end.record()
end.synchronize()
secs = start.time_till(end)*1e-3
print "CPU time:", secs
print "CPU result starts with...", a[:3]
======
(I reduced the number of iterations so it doesn't take forever on the CPU). On
my machine (3GHz Core 2 Duo, GTX280, Linux), I get:
GPU time: 0.0843682250977
GPU result starts with... [ 0.00547702 0.00547702 0.00547702]
CPU time: 8.12050439453
CPU result starts with... [ 0.00547701 0.00547701 0.00547701]
So, about a 100x speedup for the GPU version. Would be more a speedup with more
iterations (the overhead of copying the data to the GPU and back is the same
regardless). In fact, for such a small amount of data (only 32K) you can
probably significantly increase the size of the data without incurring much
more copying overhead - setting up the transfer is expensive, copying a few KB
isn't.
Have a play with the params and enjoy.
Next thing to get even more speed is to copy the data to shared memory within
each block, do the computation there and then copy the result back to main
memory when you're done. The NVIDIA docs and whitepapers should make it fairly
clear how to achieve that :)
Cheers,
Ian Cullinan
________________________________________
From: [email protected] [[email protected]] On Behalf Of Ian
Ozsvald [[email protected]]
Sent: Friday, 29 January 2010 1:29 AM
To: [email protected]
Subject: [PyCUDA] Very simple speed testing code for another beginner...
Here is some very simple speed testing code - maybe it is useful to another
beginner. I've used it to convince myself that GPUs really do go faster than
CPUs (this is useful here in the office to show my physics colleagues).
The code was adapted from hello_gpu.py. It has two halves, first it does a
simple calculation many times on the GPU and then it does the same calculation
on the CPU. Both times it uses dev.Event to count how long the operations took.
Roughly speaking on my WinXP Intel Core2 Duo 2.66GHz CPU (1 CPU used) the
9800GT GPU comes out 20-55* faster than the CPU.
In the code below a value for sin is calculated 2,000,000 times in a 400
element array. A 20-30* speedup holds for tan, sin, addition, sqrt, exp. The
pow function shows a 55* speedup. If you want to do your own testing then
replace the two references to 'sin' with your chosen function. Remember that
2,000,000 is also written twice so change it in both places to alter the number
of iterations. Extra note - the final result for 'tan' diverges quickly, 'sin'
and others seem to be mostly stable.
By lowering the iterations from 2,000,000 to 200 (in both places) then both the
CPU and GPU complete their tasks in roughly the same time.
I did a variation where 'dest' is removed and 'float *a' is referenced by
drv.InOut(a) (so a is the input parameter and is also used for the output
result) - I didn't observe any obvious speed difference.
Side note - I'm also using the NVIDIA System Monitor, I've selected all the GPU
outputs along with CPU outputs so they hover as transparent displays at the top
of the screen. Whenever the GPU is invoked you see the GPU Usage, Cooler and
Temp change.
HTHs another newbie,
Ian.
_______________________________________________
PyCUDA mailing list
[email protected]
http://host304.hostmonster.com/mailman/listinfo/pycuda_tiker.net