C 使用NEON优化ARM的卷积运算
有人能指导我使用C语言中ARM Neon Intrinsic的优点优化图像上过滤器的卷积吗?我已经用传统的C语言实现了这一点,但是,我需要时间优化代码,以便在支持NEON的ARM上实现更快的图像处理。internet上可用的资源对于使用C语言在ARM上使用NEON实现算法非常有限 我需要把一个3x3的滤镜和图像卷积起来。我想主要的问题是访问图像的3x3矩阵的循环约束。NEON Intrinsic帮助我们一次加载8字节的数据,但是如何利用这一点来访问3x3矩阵呢? 现在,我像这样访问3x3图像矩阵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图像矩
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还可以做些什么吗?我想知道。效率越高,效果越好。好吧,有太多多余的标量代码,您正在内存中迭代不连续地,仅列举两个主要问题。如果您在上发布一个适当标记的问题(因为这是工作代码),并确保它基于您当前的功能代码,那么我和其他人可以给您一些具体的改进建议。