내가 vectorisation에 대해 배우려고 노력하고, 여기에 내 원래의 C++/STL 코드계산 평균
#include <vector>
#include <vectorclass.h>
template<typename T>
double mean_v1(T begin,T end) {
float mean = 0;
std::for_each(begin,end,[&mean](const double& d) { mean+=d; });
return mean/std::distance(begin,end);
}
double mean_v2(T begin,T end) {
float mean = 0;
const int distance = std::distance(begin,end); // This is expensive
const int loop = (distance >> 2)+1; // divide by 4
const int partial = distance & 2; // remainder 4
Vec4d vec;
for(int i = 0; i < loop;++i) {
if(i == (loop-1)) {
vec.load_partial(partial,&*begin);
mean = horizontal_add(vec);
}
else {
vec.load(&*begin);
mean = horizontal_add(vec);
begin+=4; // This is expensive
}
}
return mean/distance;
}
int main(int argc,char**argv) {
using namespace boost::assign;
std::vector<float> numbers;
// Note 13 numbers, which won't fit into a sse register perfectly
numbers+=39.57,39.57,39.604,39.58,39.61,31.669,31.669,31.669,31.65,32.09,33.54,32.46,33.45;
const float mean1 = mean_v1(numbers.begin(),numbers.end());
const float mean2 = mean_v2(numbers.begin(),numbers.end());
return 0;
}
두 V1의 내가 Agner Fog's vector library
을 사용하고 바퀴를 reinvet보다는 해요 및 v2는 올바르게 작동하며 둘 다 거의 같은 시간이 걸립니다. 그러나 그것을 프로파일 링하면 std :: distance()가 표시되고 반복기를 따라 이동하는 것은 전체 시간의 거의 45 %를 차지합니다. 벡터 추가는 0.8 %로 v1보다 훨씬 빠릅니다.
웹을 검색하면 모든 예제가 SSE 레지스터에 정확하게 들어 맞는 완벽한 수의 값을 처리하는 것처럼 보입니다. 예를 들어 루프를 설정하는 것이 계산보다 훨씬 오래 걸리는 경우와 같이 사람들이 홀수의 값을 처리하는 방법은 무엇입니까?
이 시나리오를 처리하는 방법에 대한 모범 사례 또는 아이디어가 있어야한다고 생각합니다.
나는 [] 부동 취할 평균()의 인터페이스를 변경할 수는 없지만 반복자 당신이 누적 더블하자하지 않습니다 특히 당신은 이중 불필요 플로트 &을 혼합하고
충고와 마찬가지로 : 아마도 추력 라이브러리가 당신에게 흥미로울 것입니다. https://code.google.com/p/thrust/ – eraxillan
실제로 흥미로운 것 같습니다 – Ronnie