关于并行化线程ID的疑问

一般的线程ID可以通过griddim,blockdim,blockidx这些内置变量确定。
但是看书却有2种不同的计算方法。

例如:2维block下有2维线程
一种计算式:
UniqueBlockIndex = blockIdx.y * gridDim.x + blockIdx.x;
UniqueThreadIndex =UniqueBlockIndex * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x;

但是在cuda by example里的计算式:

tx = blockIdx.xblockDim.x+threadIdx.x
ty = blockIdx.y
blockDim.y+threadIdx.y
ThreadID = tx + ty * N
( N = blockDim.x * gridDim.x)
ThreadID = (blockIdx.xblockDim.x+threadIdx.x) + (blockIdx.yblockDim.y+threadIdx.y)* (blockDim.x * gridDim.x)

红色字部分不能理解。

上面的都对。第一个是先获得block,再求 thread。
第二个是 先获得线程在全局中的索引坐标,再按照二维的方式计算thread。

2种计算结果好像不同啊 ???

怎么不同了?

约去第一项和第四项,中间2项
第一种算法是
threadIdx.y * blockDim.x + blockIdx.x * blockDim.y * blockDim.x
第二种算法是
blockIdx.xblockDim.x + threadIdx.y blockDim.x * gridDim.x

再约去blockDim.x

threadIdx.y + blockIdx.x * blockDim.y ===blockIdx.x + threadIdx.y * gridDim.x???

两种方法肯定是一样的,都有其物理意义的。你写个kernel测试一下,你约分之后也是相等的。你这样约分之后,虽然表面看起来怪怪的,但并不能否定二者不同啊,约分之后好像没有物理意义,但是做某种转化之后就会相等的。