So the answer is 3.
And so here I'm showing the memory traffic required for the global version.
Here I'm showing the memory traffic required from the shared version.
I'm showing all the reads you need to do in red and all the writes you need to do in blue.
And if you sum this series, you'll find for reducing n values in shared memory
you'll do n reads and 1 write but for global memory you do 2 n reads and n writes.
So you would expect that it would run faster, which it will, and let's show that now.
So now I'm going to run the shared memory version.
And we see that it does in fact run faster.
Now we're down to 464 microseconds as opposed to 651.
But it doesn't run 3 times faster. How come?
Well, the detailed reason is that we're not saturating the memory system.
And there's numerous advanced techniques you would need to do
to totally max out the performance of reduce.
We're not doing that today, but if you're really interested in micro-optimization of this kind,
this application is a really great place to start.
You'll want to look in particular at processing multiple items per thread instead of just 1.
You'll also want to perform the 1st step of the reduction
right when you read the items from global memory into shared memory.
And you'll want to take advantage of the fact that warps are synchronous
when you're doing the last steps of the reduction.
But these are all advanced techniques.
We can talk about them on the forums if you all are interested.