Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
优化英特尔Iris的OPENCL代码_Opencl_Intel_Gpgpu - Fatal编程技术网

优化英特尔Iris的OPENCL代码

优化英特尔Iris的OPENCL代码,opencl,intel,gpgpu,Opencl,Intel,Gpgpu,我已经编写了一段opencl代码片段,希望进一步改进: global_size is 1920x1080 local size is kept NULL. I have left this to compiler. __kernel void experiment(__read_only image2d_t YIn, __write_only image2d_t YOut) { uint4 best_suited=0; uint4 temp =0; int best_sum,ss

我已经编写了一段opencl代码片段,希望进一步改进:

global_size is 1920x1080
local size is kept NULL. I have left this to compiler.

__kernel void experiment(__read_only image2d_t YIn, __write_only image2d_t YOut)
{

  uint4 best_suited=0;
  uint4 temp =0;
  int best_sum,ssum;

    int2 coord_src = (int2)(get_global_id(0), 2*get_global_id(1)+1);

    const sampler_t smp = CLK_FILTER_NEAREST | CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE;


      uint4 pixel1 = read_imageui(YIn, smp, coord_src + (int2)(-3,0));
      uint4 pixel2 = read_imageui(YIn, smp, coord_src + (int2)(-2,0));
      uint4 pixel3 = read_imageui(YIn, smp, coord_src + (int2)(-1,0));
      uint4 pixel4 = read_imageui(YIn, smp, coord_src + (int2)( 0,0));
      uint4 pixel5 = read_imageui(YIn, smp, coord_src + (int2)( 1,0));
      uint4 pixel6 = read_imageui(YIn, smp, coord_src + (int2)( 2,0));
      uint4 pixel7 = read_imageui(YIn, smp, coord_src + (int2)( 3,0));

      /* Read luma pixels of next line */                            
      uint4 pixel_nxt1 = read_imageui(YIn, smp, coord_src + (int2)(-3,2));
      uint4 pixel_nxt2 = read_imageui(YIn, smp, coord_src + (int2)(-2,2));
      uint4 pixel_nxt3 = read_imageui(YIn, smp, coord_src + (int2)(-1,2));
      uint4 pixel_nxt4 = read_imageui(YIn, smp, coord_src + (int2)( 0,2));
      uint4 pixel_nxt5 = read_imageui(YIn, smp, coord_src + (int2)( 1,2));
      uint4 pixel_nxt6 = read_imageui(YIn, smp, coord_src + (int2)( 2,2));
      uint4 pixel_nxt7 = read_imageui(YIn, smp, coord_src + (int2)( 3,2));

    /* main loop: */
    {

      best_sum= abs_diff(pixel3.x,pixel_nxt4.x) + abs_diff(pixel4.x,pixel_nxt5.x) + abs_diff(pixel5.x,pixel_nxt6.x) -8;
      best_suited.x = (pixel4.x+pixel_nxt2.x) >> 1;


      sum = abs_diff(pixel2.x,pixel_nxt2.x) + abs_diff(pixel3.x,pixel_nxt6.x) + abs_diff(pixel4.x,pixel_nxt1.x);

      if (sum < best_sum) 
      {

      best_sum = sum; 
        best_suited.x = (pixel3.x+pixel_nxt3.x) >> 1;

        sum = abs_diff(pixel1.x,pixel_nxt5.x) + abs_diff(pixel2.x,pixel_nxt6.x) + abs_diff(pixel3.x,pixel_nxt7.x) + 16;

        if (sum < best_sum) 
        {
             best_sum = sum; 
             best_suited.x = (pixel5.x+pixel_nxt1.x) >> 1;
        }
      } 

      sum = abs_diff(pixel4.x,pixel_nxt5.x) + abs_diff(pixel5.x,pixel_nxt2.x) + abs_diff(pixel6.x,pixel_nxt1.x);

      if (sum < best_sum) 
      {
       best_sum = sum; 
         best_suited.x = (pixel4.x+pixel_nxt3.x)>> 1;

         sum = abs_diff(pixel5.x,pixel_nxt3.x) + abs_diff(pixel6.x,pixel_nxt4.x) + abs_diff(pixel7.x,pixel_nxt3.x);

       if (sum < best_sum) 
       {
             best_sum = sum; 
             best_suited.x = (pixel6.x+pixel_nxt2.x) >> 1;
           }
      }
    }


      /* Pix4(0,0) is the current pixel in below calculations */
        write_imageui(YOut, coord_src, pixel4);
      /* store the result: */
      write_imageui(YOut, coord_src+(int2)(0,1),best_suited); 

}
全局_大小为1920x1080
本地大小保持为空。我把这个留给了编译器。
__内核无效实验(uuu只读映像2D_ut YIn,uuuu写入映像2D_ut YOut)
{
uint4最适合=0;
uint4温度=0;
整数最佳和,ssum;
int2坐标src=(int2)(get_global_id(0),2*get_global_id(1)+1);
常量采样器\u t smp=CLK_过滤器\u最近的| CLK_规范化的|坐标\u假| CLK_地址\u钳位\u至|边缘;
uint4 pixel1=读取图像ui(YIn,smp,coord_src+(int2)(-3,0));
uint4 pixel2=读取图像ui(YIn,smp,coord_src+(int2)(-2,0));
uint4 pixel3=读取图像ui(YIn,smp,coord_src+(int2)(-1,0));
uint4 pixel4=读取图像ui(YIn,smp,coord_src+(int2)(0,0));
uint4 pixel5=读取图像ui(YIn,smp,coord_src+(int2)(1,0));
uint4 pixel6=读取图像ui(YIn,smp,coord_src+(int2)(2,0));
uint4 pixel7=读取图像ui(YIn,smp,coord_src+(int2)(3,0));
/*读取下一行的亮度像素*/
uint4 pixel_nxt1=读取图像ui(YIn,smp,coord_src+(int2)(-3,2));
uint4 pixel_nxt2=读取图像ui(YIn,smp,coord_src+(int2)(-2,2));
uint4 pixel_nxt3=读取图像ui(YIn,smp,coord_src+(int2)(-1,2));
uint4 pixel_nxt4=读取图像ui(YIn,smp,coord_src+(int2)(0,2));
uint4 pixel_nxt5=读取图像ui(YIn,smp,coord_src+(int2)(1,2));
uint4 pixel_nxt6=读取图像ui(YIn,smp,coord_src+(int2)(2,2));
uint4 pixel_nxt7=读取图像ui(YIn,smp,coord_src+(int2)(3,2));
/*主回路:*/
{
最佳和=abs_diff(pixel3.x,pixel_nxt4.x)+abs_diff(pixel4.x,pixel_nxt5.x)+abs_diff(pixel5.x,pixel_nxt6.x)-8;
最合适的.x=(像素4.x+像素nxt2.x)>>1;
sum=abs_diff(pixel2.x,pixel_nxt2.x)+abs_diff(pixel3.x,pixel_nxt6.x)+abs_diff(pixel4.x,pixel_nxt1.x);
如果(总和<最佳总和)
{
最佳和=和;
最佳匹配.x=(像素3.x+像素nxt3.x)>>1;
sum=abs_diff(pixel1.x,pixel_nxt5.x)+abs_diff(pixel2.x,pixel_nxt6.x)+abs_diff(pixel3.x,pixel_nxt7.x)+16;
如果(总和<最佳总和)
{
最佳和=和;
最合适的.x=(像素5.x+像素nxt1.x)>>1;
}
} 
sum=abs_diff(像素4.x,像素nxt5.x)+abs_diff(像素5.x,像素nxt2.x)+abs_diff(像素6.x,像素nxt1.x);
如果(总和<最佳总和)
{
最佳和=和;
最佳匹配.x=(像素4.x+像素nxt3.x)>>1;
sum=abs_diff(像素5.x,像素nxt3.x)+abs_diff(像素6.x,像素nxt4.x)+abs_diff(像素7.x,像素nxt3.x);
如果(总和<最佳总和)
{
最佳和=和;
最合适的.x=(像素6.x+像素nxt2.x)>>1;
}
}
}
/*Pix4(0,0)是以下计算中的当前像素*/
写入图像用户界面(YOut、coord、src、pixel4);
/*存储结果:*/
编写图像用户界面(YOut,coord_src+(int2)(0,1),最适合);
}
我试过以下几件事: 1) abs_diff是内置函数,用位代码替换abs_diff不会带来任何改进

2) 使用“英特尔Vtune”和saw分析了它的性能,执行单元在30%的时间内处于空闲状态。GPU内存读取为7.6GB/秒,写入为3.942GB/秒。三级缓存未命中数接近177x10^9,计算线程接近35个LAC。此外,采样器瓶颈为8.3%

进一步思考: 1) 我不知道读取本地内存中的数据是否对我有利。因为本地内存缓存线访问与访问英特尔体系结构上的三级缓存相同。通过图像api读取,我已经在访问图像对象的缓存,即纹理内存。如果我写这样的代码,我能想到的唯一帮助就是减少采样器瓶颈: __本地smem[256]; smem[get_local_id(0)=读取图像UI(YIn、smp、coord_src)

2) 我也不知道这里的最佳工作组规模应该是多少

有人能详细地向我解释一下这段代码是如何优化的吗?我该如何减少执行空闲时间、计算线程、三级缓存未命中以及增加GPU内存的读写访问。如果你能重新编写这段代码,那将非常有帮助。

1)我猜本地内存可能会有所帮助。即使它在三级缓存中,你也会发现如果你在SLM中小心地安排你的负载,而不是让所有的EU同时敲打L3,那么得到更少的缓存抖动。如果你有时间进行实验,至少值得一试

2) 如果没有SLM,我建议在Intel BDW上尽可能多的工作组(256或16x16,具体取决于平铺方式)。这对于工作量小得多的短内核更重要。对于像您这样的大内核,这可能无关紧要

如果您选择SLM路线,那么我们需要一个工作组大小,以便切片上的所有线程都尽可能多地使用(但不能更多)。经验法则是每个工作项64字节。。我认为这是假设SIMD16编译,但由于我们无法控制您最终可能编译SIMD8。因此,也请尝试每个工作项128字节。请参阅中的幻灯片34和44