{

int src_cn = AVICCV_MAT_CN(src->type);
int depth = AVICCV_MAT_DEPTH(src->type);
int elem_size = AVICCV_ELEM_SIZE(src->type);
int size = elem_size / src_cn;
int i, j, k, size_multi_cn = 0;
double sum = 0;
AvicScalar add_square_value;
switch (depth)
{
case AVICCV_8U:
{

	for (k = 0; k < src_cn; k++)
	{
		size_multi_cn = k * size;
		sum = 0;
		for (i = 0; i < src->rows; i++)
		{
			for (j = 0; j < src->cols; j++)
			{
				sum += AVIC_CV_SQR(*(unsigned char*)(src->data.ptr + (i * src->cols + j)*elem_size + size_multi_cn));
			}
		}
		add_square_value.val[k] = sum;
	}
	break;
}
case AVICCV_32F:
{
	if(src_cn == 3)
	{	
		float* src_ptr = src->data.fl;
		for (k = 0; k < src_cn; k++)
		{
			size_multi_cn = k * size;
			sum = 0;
			for (i = 0; i < src->rows; i++)
			{
				for (j = 0; j < src->cols; j++)
				{
					sum += AVIC_CV_SQR(*(float*)(src->data.ptr + (i * src->cols + j)*elem_size + size_multi_cn));
				}
			}	
			add_square_value.val[k] = sum;
		}
	}
	else
	{
		float* src_ptr = src->data.fl;
		float add[4] ={0} ;
		float* add_ptr = add;
		#ifndef WITH_NEON
			#ifdef WITH_OMP
				#pragma omp parallel for private(j)
			#endif
				for (k = 0; k < src_cn; k++)
				{
					size_multi_cn = k * size;
					sum = 0;
					for (i = 0; i < src->rows; i++)
					{
						for (j = 0; j < src->cols; j++)
						{
							sum += AVIC_CV_SQR(*(float*)(src->data.ptr + (i * src->cols + j)*elem_size + size_multi_cn));
						}
					}	
					add_square_value.val[k] = sum;
				}
		#else
			#ifdef WITH_OMP
				#pragma omp parallel for private(j)
			#endif
				for(i = 0 ; i < src->rows ; i++)
				{
					src_ptr = src->data.fl + i * src->cols * elem_size;
					printf("1111 ");////////////////////////////
					for(j = 0; j <= src->cols * src_cn - 4; j += 4)
					{	
						float32x4_t temp = vld1q_f32(src_ptr + j * size);
						float32x4_t re = vmulq_f32(temp , temp);
						float32x4_t re1 = vld1q_f32(add_ptr);
						vst1q_f32(add_ptr , vaddq_f32(re, re1));
					}
					for(; j <= src->cols * src_cn ; j ++)
					{
						add_square_value.val[0] += AVIC_CV_SQR(*(float*)(src->data.ptr + i * src->cols *elem_size + j * size));
					}
					printf("2222 ");////////////////////////////
					add_square_value.val[0] += add[0];
					add_square_value.val[0] += add[1];
					add_square_value.val[0] += add[2];
					add_square_value.val[0] += add[3];
					
					printf("%.2f ",add_square_value.val[0]);////////////////////////////
				}
		#endif
	}
	break;
}

}
return(add_square_value);

}

分析该段代码中使用NEON和openmp优化部分有何问题内容:在分析这段代码中使用NEON和OpenMP优化部分的问题之前,首先需要了解NEON和OpenMP的基本概念和使用方式。

NEON是ARM架构下的SIMD(单指令多数据)指令集,可以在一次指令中同时处理多个数据元素,从而提高并行计算的效率。NEON的优化需要使用特定的指令和数据类型,并且需要对内存访问进行对齐操作。

OpenMP是一种并行编程模型,可以将程序的某些部分标记为并行执行的区域,然后由编译器和运行时系统来自动处理并行化的细节。OpenMP的优化需要合理地进行任务划分和负载均衡,以确保各个线程之间的工作量均衡。

在对这段代码进行分析时,可以发现以下问题:

  1. NEON优化部分: a. 在使用NEON进行优化时,代码中的NEON指令使用不正确。例如,代码中使用了vld1q_f32和vst1q_f32加载和存储指令,但是加载和存储的地址计算部分存在问题,无法正确地加载和存储数据。 b. 在使用NEON指令时,需要对内存访问进行对齐操作,以保证数据的正确加载和存储。代码中没有对内存进行对齐操作,可能导致NEON指令的运行出错。

  2. OpenMP优化部分: a. 在使用OpenMP进行优化时,代码中的并行化标记和任务划分存在问题。代码中使用了#pragma omp parallel for进行并行化循环,但是循环的并行化可能存在数据依赖和负载不均衡的问题。 b. 在使用OpenMP进行并行化时,需要考虑数据的共享和同步问题。代码中没有对共享数据和临界区进行合理的同步操作,可能导致并发访问的错误。

综上所述,该段代码中使用NEON和OpenMP优化部分存在NEON指令使用不正确、内存访问未对齐、OpenMP循环并行化存在数据依赖和负载不均衡等问题。需要对这些问题进行修正和改进,以确保优化的正确性和效果。

AvicScalar avic_mat_add_square(const AvicMat* src) - Efficient Matrix Element Squaring and Summation

原文地址: http://www.cveoy.top/t/topic/qA9m 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录