越界问题

  • 1 replies
  • 401 views
越界问题
« 于: 四月 17, 2019, 11:34:55 am »
继上一次的moving average问题,我现在采用shared memory来做,每个block处理256个数据。比如,我计算每个单元右边16个数据的平均值,考虑到最后面24个(实际24,是因为不是紧靠的16个数据,中间有8个保护单元)数据右边不够24个数了,那么我就得在这个block的共享内存里外挂一个24个数据的数组,存放下一个block的前24个数据。像这样:
for (int i = 0; i < 24; i++)
      extra_right = real[(bid + 1) * 256 + i];
那么对于我最后一个bid,它的real[]索引应该是不存在的,这个时候会怎样?我现在只计算了一个方向,左边和上下还没算,还无法验证计算结果的准确性,但是运行没报错,速度也确实快很多。

Re: 越界问题
« 回复 #1 于: 四月 17, 2019, 03:47:03 pm »
继上一次的moving average问题,我现在采用shared memory来做,每个block处理256个数据。比如,我计算每个单元右边16个数据的平均值,考虑到最后面24个(实际24,是因为不是紧靠的16个数据,中间有8个保护单元)数据右边不够24个数了,那么我就得在这个block的共享内存里外挂一个24个数据的数组,存放下一个block的前24个数据。像这样:
for (int i = 0; i < 24; i++)
      extra_right = real[(bid + 1) * 256 + i];
那么对于我最后一个bid,它的real[]索引应该是不存在的,这个时候会怎样?我现在只计算了一个方向,左边和上下还没算,还无法验证计算结果的准确性,但是运行没报错,速度也确实快很多。

(1)你原本怎么做就怎么做。例如原本用texture,越界自动返回最后不越界的值,则你依然填充不越界的值;如果原本要求返回0值,则你填充0值;如果你原本要求卷绕,则你这里卷绕。类似这样的。这个问题你应当比我清楚。按照原样处理即可。

(2)如果不想填充,则可以用if来实现边界,例如你最后的需要0值,可以直接if判断位置,一定情况下直接设定为0即可。

(3)如果不想填充0值这种,也不想if判断,则可以拆分kernel,拆分成中间区域和边界区域的。中间区域执行一次坐标偏移映射即可,此时100%不越界。而边界处的则可以常规处理(填充或者用if),这样往往可以取得性能和存储器容量(边界填充)和计算量(if判断)上的最佳效果,代价是你得写两种情况的kernel。