저는 데이터 스트림으로 C에서 작업하고 있습니다. 기본적으로 n 밀리 초마다 6 개 요소의 열 배열을받습니다. 각 데이터 행의 최대 값을 계산하고 싶습니다.
이를 명확히하기 위해 이것은 내 데이터의 모습입니다 (이것은 장난감 예제이며 실제로 수천 개의 열을 획득 할 것입니다).
[6] [-10] [5]
[1] [5] [3]
[5] [30] [10]
[2] [-10] [0]
[-2][5] [10]
[-5][0] [1]
그래서 기본적으로 (말했듯이) n 밀리 초마다 데이터 열을 수신하고 최대 및 최소 값을 행 단위로 계산하고 싶습니다. 따라서 이전 예에서 결과는 다음과 같습니다.
max_values=[6,5,30,2,10,1]
min_values=[-10,1,5,-10,-2,-5]
나는 전체 행렬에 액세스 할 수 없으며 n 밀리 초마다 수신하는 6 개 요소의 단일 열에 대해서만 작업 할 수 있음을 지적하고 싶습니다.
이것은 지금까지의 간단한 코드 알고리즘입니다 (더 큰 프로젝트의 일부이므로 전체 코드를 생략하겠습니다).
for(int i=0;i<6;i++){
if(input[i]>temp_max[i]){
temp_max[i]=input[i];
}
if(input[i]<temp_min[i]){
temp_min[i]=input[i];
}
}
여기서 input
, temp_max
그리고 temp_min
모두 차원 6의 부동 배열입니다. 기본적으로 내 코드는 새 입력 배열을 사용할 수있을 때마다이 코드를 실행하고 그에 따라 최대 값과 최소값을 업데이트합니다.
성능에 관심이 있기 때문에 (임베디드 시스템에서 실행 됨) 코드의이 부분을 개선 할 수있는 방법이 있습니까? 두 배열의 각 단일 요소에 대한 비교를 호출하는 것은 가장 현명한 생각이 아닙니다.
분기는 특히 임베디드 시스템에서 느립니다 . 스칼라 계산도 마찬가지 입니다. 바라건대, 타겟 프로세서가 NEON SIMD 명령어 세트를 지원하는 ARM 기반 프로세서 인 것 같습니다 (분명히 64 비트 ARM-V8 A53 아키텍처를 기반으로하는 프로세서 ). NEON은 행에서 4 개의 32 비트 부동 소수점 연산을 계산할 수 있습니다. 이것은 현재 코드 (컴파일러가 분명히 벡터화에 실패 함)보다 훨씬 빠릅니다.
다음은 예제 코드입니다 (테스트되지 않음).
void minmax_optim(float temp_min[6], float temp_max[6], float input[6]) {
/* Compute the first 4 floats */
float32x4_t vInput = vld1q_f32(input);
float32x4_t vMin = vld1q_f32(temp_min);
float32x4_t vMax = vld1q_f32(temp_max);
vMin = vminq_f32(vInput, vMin);
vMax = vmaxq_f32(vInput, vMax);
vst1q_f32(temp_min, vMin);
vst1q_f32(temp_max, vMax);
/* Remainder 2 floats */
float32x2_t vLastInput = vld1_f32(input+4);
float32x2_t vLastMin = vld1_f32(temp_min+4);
float32x2_t vLastMax = vld1_f32(temp_max+4);
vLastMin = vmin_f32(vLastInput, vLastMin);
vLastMax = vmax_f32(vLastInput, vLastMax);
vst1_f32(temp_min+4, vLastMin);
vst1_f32(temp_max+4, vLastMax);
}
결과 코드는 훨씬 빨라야합니다. 이 벡터화 된 구현의 명령어 수가 조건부 점프 명령어가없는 참조 구현보다 훨씬 적다는 것을 금 볼트에서 볼 수 있습니다 .
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다