2012-10-25 3 views
2

프로파일 러를 실행하면 시간이 많이 걸리는 코드가 vdist이라는 것을 알 수 있습니다. 지구를 타원체로 생각하는 지구상의 두 지점 사이의 거리를 측정하는 프로그램입니다. 코드는 표준으로 보입니다. 어디서 어떻게 개선 될 수 있는지 알 수 없습니다. 초기 의견은 이미 벡터화되었다고 말합니다. MEX 파일로 사용할 수있는 다른 언어로 된 파일이 있습니까? 내가 원하는 건 시간 효율성면에서 개선이다. 다음은 Matlab FEX의 코드에 대한 링크입니다.벡터화 된 Matlab 함수 최적화

http://www.mathworks.com/matlabcentral/fileexchange/8607-vectorized-geodetic-distance-and-azimuth-on-the-wgs84-earth-ellipsoid/content/vdist.m

기능은 루프 된 직후 내에서 호출되는

   109 for i=1:polySize 
       110 % find the two vectors needed 
     11755 111 if i~=1 
0.02 11503 112  if i<polySize 
0.02 11251 113   p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(i+1,:);  
     252 114  else 
     252 115   p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(1,:); %special case for i=polySize 
     252 116  end 
     252 117 else 
     252 118   p0=Polygon(i,:); p1=Polygon(polySize,:); p2=Polygon(i+1,:); %special case for i=1 
     252 119 end 
0.02 11755 120 Vector1=(p0-p1); Vector2=(p0-p2); 
0.06 11755 121 if ~(isequal(Vector1,Vector2) || isequal(Vector1,ZeroVec) || isequal(Vector2,ZeroVec)); 
       122  %determine normals and normalise and 
0.17 11755 123  NV1=rotateVector(Vector1, pi./2); NV2=rotateVector(Vector2, -pi./2); 
0.21 11755 124  NormV1=normaliseVector(NV1); NormV2=normaliseVector(NV2); 
       125  %determine rotation by means of the atan2 (because sign matters!) 
     11755 126  totalRotation = vectorAngle(NormV2, NormV1); % Bestimme den Winkel totalRotation zwischen den normierten Vektoren 
     11755 127  if totalRotation<10 
     11755 128   totalRotation=totalRotation*50; 
     11755 129  end 
0.01 11755 130  for res=1:6 
0.07 70530 131   U_neu=p0+NV1; 
17.01 70530 132   [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
0.02 70530 133   a12=a12+1/6.*res*totalRotation; 
     70530 134   ddist=1852*safety_distance; 
4.88 70530 135   [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12); 
0.15 70530 136   extendedPoly(f,:)=[lon2,lat2];f=f+1; 
< 0.01 70530 137  end 
     11755 138 end 
     11755 139 end 
+0

병목 역할되는 함수 내 선이 무엇입니까? 또한이 함수를 호출하는 방법의 예를 보여줄 수 있습니까? 루프 내에서 스칼라를 사용하여 호출하는 경우 벡터화 된 코드의 이점을 얻을 수 없습니다. – slayton

+0

벡터화 된 입력을 제공했는지 확인하십시오.이 알고리즘의 일반적인 성능을 향상시키기는 쉽지 않을 것입니다. 그러나 사용하지 않는 부분을 잘라낼 수 있습니까? –

+0

@ slayton- 나는 위의 호출 루프를 포함시켰다. 병목 현상이 발생하는 한, 몇 줄의 줄이 아니라 모든 시간이 걸리지 만 그 종류는 분산되어 있습니다. 예, 일부 줄은 다른 줄보다 시간이 오래 걸리지 만 줄의 가장 높은 줄은 전체 기능의 10 %입니다. – Vikram

답변

2

게시 된 코드를 자세히 연구해도 아무런 이유없이 vdist에 대한 호출이 루프 내부에서 만들어진 이유를 알 수 없습니다.

내가 루프 내에서 코드 블록을 최적화하려고 할 때, 내가 찾고자하는 것들 중 하나는 불변하는 문장입니다. 즉, 각 호출에서 동일하며, 따라서 호출에서 제외 될 수 있습니다. 고리.

내가 L131에 p0NV1 만 우측에 나타나는 변수를

  • 를 참조

    130  for res=1:6 
    131   U_neu=p0+NV1; 
    132   [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
    133   a12=a12+1/6.*res*totalRotation; 
    134   ddist=1852*safety_distance; 
    135   [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12); 
    136   extendedPoly(f,:)=[lon2,lat2];f=f+1; 
    137  end 
    

    보면, 그들은 단지 다른 루프 내부의 우측에 표시되므로이 문장은 루프 불변이고 루프에서 들어 올릴 수 있습니다. 아마도 작은 시간 만 절약 할 수 있습니다.

  • 에서 다시 한 번, 나는 다른 작은 시간 절약을 위해 다시 루프에서 빠져 나올 수있는 또 다른 루프 불변의 문장을 본다.
  • 하지만 아주 자세히 살펴보기 시작한 이유는 vdist에 대한 호출이 루프 내부에있는 이유는 알 수 없습니다. 해당 할당의 rhs 값은 루프에서 수정되지 않습니다 (U_neu 제외). 그러나 이미 루프에서 벗어났습니다. 이것이 내가 함께 결국 무엇을, 어떤이 조금 남아 있었다

을 정리하기 :

U_neu=p0+NV1; 
[pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1)); 
ddist=1852*safety_distance; 
for res=1:6 
    extendedPoly(f,:) = vreckon(p0(:,2),p0(:,1),ddist, a12+1/6.*res*totalRotation); 
    f=f+1; 
end 
+0

@ Mark- 답장을 보내 주셔서 대단히 감사합니다. 매우 도움이되었습니다. 자, 때마다 나는 불변의 진술을 내부에서 찾을 루프를 참조하십시오. 코드가 작성된 동안 성능은 문제가 아니었고, 그 이유는 거기에 몇 가지 불변의 진술이있었습니다. 다시 한 번 감사드립니다! – Vikram

1

있는 옵션이 FEX 파일을 다시 작성하는 것입니다 (현재는 가장 많은 시간이 소요 라인과 같은 기능을 찾을 수 있습니다) GPU를 사용할 수있는 방법으로 예를 들어 부드러운 방법은 Jacket이라는 도구 상자입니다.

+0

@ nate- 내 PC (i7 3.4Ghz, 8GB RAM)에는 전용 그래픽이 없습니다. 그것은 내장 된 그래픽 카드에 Intel HD 4000을 가지고 있습니다. 그 최고의 인텔은 아직까지 넣었다. 그러나 나는 그것이 재킷과 호환되지 않는다고 생각한다. 하지만 질문이 있습니다. MATLAB이 주어진 리소스 중에서 최선을 다하고 있는지 어떻게 확신 할 수 있습니까? – Vikram

+3

matlab에 내장 된 함수에서 벗어날 수있는 한계가 있습니다. 일부는 고도로 최적화되어 있으며 어떤 것보다 빠르지 만 그렇지 않은 것도 있습니다. vdist는 사용자가 작성한 함수이기 때문에, 여러분은 그것을 구별 할 수 있고 여러분이 정말로 모든 warnings \ messages \ different cases를 필요로 하는지를 볼 수 있으며, 여러분의 필요에 가장 잘 맞는 버전을 얻을 수 있습니다. 때로는 double 대신 single을 사용하면 속도가 향상되고 때로는 int16 등이됩니다. 사용하는 기계가 있으면 재킷을 사용할 수 없으며 matlab에 제한을 가하면 그만큼 좋은 결과를 얻을 수 있습니다 ... – bla