So here is my code for this. I'll start by setting k equal to 32 and here is the actual code.
I begin by figuring out the locations of the tile corners.
This is going to tell me where I need to start writing in the output and start reading from the input--
so just a little book keeping and giving things variable names that mean something to me.
But as you can see the, the place where I start
reading the i value is a function of which block we're in times the width of the tile
because each tile is responsible for 1 block and that's the case.
And the j value is the same but in y, in y instead of x, and the output simply inverts y and x.
Okay, so now that I know where I need to read to write my tile,
I'm going to want to know which element of the tile to read and write from,
and just a shorthand to make the code a little more readable.
I'm going to set x to thread index .x, and y to threat index y.
So now, the code itself is really simple.
I declare my floating point array in shared memory k by k array of tiles,
and I read from global memory, and write the result into shared memory.
So here's my read from global memory and its function of where the tile starts
plus which thread I'm responsible, or which element this thread is responsible for in the tile.
To avoid an extra sync threads, I'm going to go
ahead and write this into shared memory in transposed fashion.
So it's not tile x y, it's tile y x. Okay, that saves one of these sync thread's barriers.
Now I've got the transpose tile sitting in shared memory.
It's already been transposed, and I want to write it out to global memory.
And I want to write it out in coalesced fashion, so adjacent threads write adjacent locations and memory.
In other words, adjacent threads are varying by x the way I've set this out.
So here's my write to global memory after my read to from a shared memory.
You could have done this in 2 sync threads.
You could have read this in the shared memory, performed the transpose,
and written it out to global memory.
And you have needed a sync threads after reading it in to shared memory
and again after performing the transpose.
So, if you did that I encourage you to go back
and convert it to this single version, and see how much faster it goes.
Let's go ahead and run this on my laptop. Okay, there's 2 interesting things to note here.
One is that the amount of time taken by the parallel per element code--
the kernel that we had before--actually went up.
It's almost twice as slow now as it was before.
And if you think about it this code didn't change at all, except that we changed the value of k.
We changed the size of the thread block that's being used in this code.
We're going to come back to that. That's going to give us a hint as to a further optimization.
In the meantime, transpose parallel per element tiled, our new version,
is a little bit faster--not a lot faster and that's kind of disturbing.
We should have gone to perfectly coalesced loads and stores which should have made a difference.
Let's go ahead and fire up NVVP again and see what happened.
所以这里是我的代码。我会通过设置 k 等于 32来开始， 这里是实际的代码。
我首先找出图块转角的位置。
这将告诉我需要从哪儿开始写入到输出 以及从哪里开始从输入读取——
所以只是很小的记帐式记录并给变量赋予对我有意义的名称。
但正如你可以看到的，我开始
读 i 值的地方是我们所在的块乘以图块宽度的一个函数
因为每个图块是负责 1 块，就是这种情况。
而J 的值是一样的，不过是在 y，在y 而不是在x, 输出仅仅是反转 y 和 x。
好的，所以现在我知道在哪里我要读写我的图块，
我想知道要从图块的哪个元素读取和写入，
只是为了使代码更具可读性的简写形式。
我将设置x 到线程索引.x，以及y 到线程索引y。
所以，现在，代码本身是很简单的。
我定义我共享内存中的浮点数组为 k 乘以图块数组K。
然后，我从全局内存中读取并将结果写入到共享内存。
所以这就是我从全局内存的读取和图块开始位置的公式
再加上我负责的线程，或在图块中这个线程所负责的元素。
为省去额外的同步线程，我将先
以转置的方式将它写入共享内存。
所以它不是图块 x y，它是图块 y x。 好吧, 这可以节省这些同步线程的一个屏障。
我现在共享内存中存在转置的图块。
它已经被转置，我想要将它写出到全局内存。
我想以合并的方式写出，这样相邻线程写入相邻位置和内存。
换言之，相邻线程由我确定的方式在 x 上变化，
所以这是我从共享内存读出然后写入全局内存的结果。
你可以2个同步线程完成这一步。
你有可能在共享内存中读取这个，然后进行转置，
接着把它写入到全局内存。
你在把它读取到共享内存后需要一个同步线程
同样的在执行转置之后也需要一个同步线程。
所以，如果你那样做了，我鼓励你回去
将其转换为这个单一版本，并看看它变得有多快。
让我们继续，在我的笔记本电脑上运行。好的，这里有两件有趣的事情需要注意。
一是，每个元素代码的并行——我们以前有的内核——
所需的时间实际上升了。
它现在几乎比之前要慢2倍。
并且，如果你想想，此代码一点也没有改变，除了我们改变了 k 值。
我们改变了在此代码中使用的线程块的大小。
我们要回到那里。这会给我们一种进一步优化的提示。
在此期间，每个平铺元素都转置为并行， 我们的新版本。
是更快一点点了——不是快很多，那是有点令人烦恼。
我们应该去完全合并的负载和存储，那些应该有什么区别。
让我们继续并再次启动 NVVP，看看发生了什么事。