Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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
C 使用NEON优化ARM的卷积运算_C_Optimization_Arm_Simd_Neon - Fatal编程技术网

C 使用NEON优化ARM的卷积运算

C 使用NEON优化ARM的卷积运算,c,optimization,arm,simd,neon,C,Optimization,Arm,Simd,Neon,有人能指导我使用C语言中ARM Neon Intrinsic的优点优化图像上过滤器的卷积吗?我已经用传统的C语言实现了这一点,但是,我需要时间优化代码,以便在支持NEON的ARM上实现更快的图像处理。internet上可用的资源对于使用C语言在ARM上使用NEON实现算法非常有限 我需要把一个3x3的滤镜和图像卷积起来。我想主要的问题是访问图像的3x3矩阵的循环约束。NEON Intrinsic帮助我们一次加载8字节的数据,但是如何利用这一点来访问3x3矩阵呢? 现在,我像这样访问3x3图像矩

有人能指导我使用C语言中ARM Neon Intrinsic的优点优化图像上过滤器的卷积吗?我已经用传统的C语言实现了这一点,但是,我需要时间优化代码,以便在支持NEON的ARM上实现更快的图像处理。internet上可用的资源对于使用C语言在ARM上使用NEON实现算法非常有限

我需要把一个3x3的滤镜和图像卷积起来。我想主要的问题是访问图像的3x3矩阵的循环约束。NEON Intrinsic帮助我们一次加载8字节的数据,但是如何利用这一点来访问3x3矩阵呢?

现在,我像这样访问3x3图像矩阵

for(i=1;i<width;i++) // i = rows                                                                                                       
        {                                                                                                             
                if(i!=1)                                                                                                                       
                        fseek(fp, 1078+(width*(i-1)), SEEK_SET);                                                                               
                for(j=1;j<height-1;j++) // j = columns                                                                                         
                {                                                                                                                              
                        if(j!=1)                                                                                                               
                                fseek(fp, 1077 + (i*width) + j , SEEK_SET);                                                                    
                        for(k=0;k<9;k+=3)                                                                                                      
                        {                                                                                                                      
                                data[k] = getc(fp);                                                                                            
                                data[k+1] = getc(fp);                                                                                          
                                data[k+2] = getc(fp);                                                                                          
                                //fread(buf, sizeof(char), width - 3, fp);                                                                     
                                fseek(fp, width - 3, SEEK_CUR);                                                                                
                        }                                                                                                                      
                        pixel = vld1_u8(&data);                                                                                                
                        pixel_last = data[8];                                                                                     
                        result = vmul_u8(kernel,pixel);                                                                                        

                        for(k=0;k<8;k++)                                                                                                       
                                sum += result[k];                                                                                              

                        sum += pixel_last * kernel_last;                                                                                       
                        sum = sum/9;                                                                                                           
                        sum = sum > 255 ? 255 : sum;                                                                                           
                        imageData[i*width + j]= sum;                                                                                           

                }                                                                                                                              

        }                             

for(i=1;i以上评论中@PaulR的回答起到了作用。立即在缓冲区中读取图像数据,然后应用过滤算法将计时减少到近10倍

这就是我所做的

fread(imageData, sizeof(unsigned char), imgDataSize, fp);                                    

for(i=0;i<width;i++) // i = rows                                                                       
        {                                                                           
                start_1= clock();                                      
                for(j=0;j<height;j++) // j = columns                                    
                {                                                                                    
                        for(k=0;k<9;k+=3)                                                                      
                        {                                                           
                                data[k] = imageData[i*width + j];
                                data[k+1] = imageData[(i+1)*width + (j+1)];             
                                data[k+2] = imageData[(i+2)*width + (j+2)];                          
                        }                                                                                      
                        pixel = vld1_u8(&data);                                     
                        pixel_last = data[8];                                       
                        result = vmul_u8(kernel,pixel);                                                        

                        for(k=0;k<8;k++)                         
                                sum += result[k];                                       

                        sum += pixel_last * kernel_last;                                                       
                        sum = sum/9;                                                
                        sum = sum > 255 ? 255 : sum;             
                        newimageData[i*width + j]= sum;                                 

                }                                                                                              
        }                                                                                                      
fread(图像数据,sizeof(无符号字符),imgDataSize,fp);

对于(i=0;i您可以在此处提出您的问题:首先,将文件i/O与筛选代码分离。使用一个函数将图像数据读取到内存中的源缓冲区,然后应用筛选例程,使其从源缓冲区读取并将其输出写入第二个缓冲区。这将使筛选更易于实现,而且将允许您将优化的筛选代码与(速度慢得多)文件I/O分开进行基准测试。我在
intrinsics
处停止读取。谢谢@PaulR!您的解决方案运行良好:)要提高上述过滤代码的效率,您还有很多工作要做,但如果这已经足够快满足您的需要,那么您可以保持原样。您能解释一下@PaulR还可以做些什么吗?我想知道。效率越高,效果越好。好吧,有太多多余的标量代码,您正在内存中迭代不连续地,仅列举两个主要问题。如果您在上发布一个适当标记的问题(因为这是工作代码),并确保它基于您当前的功能代码,那么我和其他人可以给您一些具体的改进建议。