2016-08-20 2 views
1

각 픽셀의 값을 네 인접 픽셀의 중앙값을 사용하여 결정해야하는 비디오 처리 코드가 있습니다. 그래서, 나는 4 바이트 배열을 가지고 있으며 성능면에서 중간 값을 찾아야 만합니다. 먼저 배열을 정렬 한 다음 2 개의 중간 값의 평균을 계산해야합니다. 나는 이미지의 픽셀 절반을 위해 그렇게해야 병렬 적으로 처리 할 수 ​​있습니다.C# SIMD System.Numerics.Vector를 사용하여 정렬/중앙 정렬

System.Numerics.Vector를 사용하여이 작업을 수행 할 수 있습니까?

또한 분명하지 않습니다. docs : System.Numerics.Vector에서 x86 코드 용 또는 x64 용 SIMD를 만듭니 까?

답변

2

이 답변에서는 데이터를 올바른 위치에서 얻는 것에 신경 쓰지 않고 단지 중간 비즈니스에 불과합니다.

왼쪽/위/오른쪽/아래에 별도의 벡터가 있다고 가정합니다. 그것들을 벡터로 묶어 두는 것은 매우 짜증나게 할 것이며, 간단한로드로는 할 수 없기 때문에 실제로 설정하는 것이 더 어렵습니다.

4 개의 중앙값을 찾으려면 많은 비교와 ConditionalSelects가 필요하지 않습니다. 최소값과 최대 값을 찾아서 제거하면됩니다. 최소값과 최대 값을 찾는 것은 쉽지만, Vector.MinVector.Max을 두 번 적용하면됩니다. "제거"는 4 가지의 합에서 빼는 것을 의미합니다. 물론 결과가 2 바이트의 합계를 나타 내기 때문에 바이트 자체에 적합하지 않으므로 [불행하게도 대부분의 계산이 16 비트로 처리되어 처리량이 절반으로 줄어 듭니다. 결국, 두 개의 중간 값의 합을 1 씩 이동하여 평균을 구하십시오. 다시 8 비트로 변환 할 수 있습니다.

또는 짧은

, 중간 수준의 4 정렬하지 않고 :

median = (a + b + c + d - min(a, b, c, d) - max(a, b, c, d)) >> 1; 

선택적으로 당신은 둥근 업 평균을 얻기 위해 이동하기 전에 하나를 추가 할 수 있습니다.

1 : 그렇지 않은 경우 계산을 완료하면 모든 문제가 해결됩니다. 중간 값이 3 인 경우 결과는 이 8 비트로 맞으므로 확대하지 않고 완료 할 수 있습니다 (합계가 줄을 수도 있지만 빼기는 같은 값만큼 "unwrap"합니다). 물론 XOR로도 처리 할 수 ​​있습니다. XOR을 사용하면 더 명확하게 작동합니다.

+0

대단원! Btw 벡터가 x86에서 SIMD를 생성하는지 알고 있습니까? –

+0

@EtienneCharland 내가 아는 한 x64에서만 사용할 수 있습니다. – harold

+0

그런 종류의 것이 무의미합니다. 다행히 미래에 확장 할 것입니다 –