2013-08-03 4 views
1

벡터에 저장된 데이터에 액세스하는 몇 가지 방법을 확인하기 위해 벤치마킹 프로그램을 작성했습니다. tww 중첩 된 for 루프를 사용하여 에 맞 춥니 다. A) 첫 번째 루프의 반복마다 벡터 객체에 대한 참조를 만들고 두 번째 루프에서 두 번째 루프를 사용합니다. B) 포인터를 만들고 해당 포인터를 참조에 저장합니다. 액세스 [] 연산자 D와 직접 벡터 객체))가 제 1 루프의 각 반복에 대한 벡터의 객체와 루프 C위한 제에서 해당 포인터를 사용하는 제 1 루프에서 자동 &을 사용for 루프 내에서 벡터 요소에 액세스하는 방법 몇 가지 비교

이러한 중첩 된 for 루프는 타이밍 함수와 함께 다른 루프에 중첩되어 있습니다. for 루프가 0에서 100까지 진행되는 동안 테스트를 여러 번 실행하면 이러한 모든 방법에 대해 항상 같은 결과가 나타납니다. 항상 0.150 초이며 0.02 %의 변동이 있습니다.

내 질문 :

1) 내 테스트가 맞습니까?

2) 제가 빠뜨린 몇 가지 최적화/다른 접근법이 있습니까?

여기에 내 코드

#include <iostream> 
#include <chrono> 
#include <ratio> 
#include <ctime> 
#include <vector> 
using namespace std; 
using namespace std::chrono; 


struct my_struct{ 

    vector<float> data; 

    my_struct(int N, float x){ 

     for(int i=0;i<N;i++){ 
      data.push_back(cos(x+i)); 
     } 
    } 

    void work(){ 
     for(int i=0;i<data.size();i++){ 
      data[i]=data[i]*data[i]; 
     } 
    } 

}; 

int main(){ 
int N=100; 
vector<my_struct> stuff; 
for(int k=0; k<N; ++k){ 
    stuff.push_back(my_struct(100,sin(k))); 
} 

vector<duration<double>> results_t1,results_t2,results_t3,results_t4; 
high_resolution_clock::time_point t1 = high_resolution_clock::now(); 
for(int k=0; k<N; ++k){ 
    int which=0; //this is used to choose what method of access will be used 
    switch(which){ 
     case 0:{ //pointer 
      my_struct * thing=NULL; 
      for(int i=0; i<N;++i){ 
       high_resolution_clock::time_point t2 = high_resolution_clock::now(); 
       for(int j=0; j<N;++j){ 
        thing =&stuff[j]; 
        for(int jj=0; jj<N;++jj) 
         thing->work(); 
       } 
       duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 
       results_t1.push_back(time_span); 
       t1=t2; 
      } 
      break; 
     } 

     case 1:{ //direct access 
      for(int i=0; i<N;++i){ 
       high_resolution_clock::time_point t2 = high_resolution_clock::now(); 
       for(int j=0; j<N;++j){ 
        for(int jj=0; jj<N;++jj) 
         stuff[j].work(); 
       } 
       duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 
       results_t2.push_back(time_span); 
       t1=t2; 
      } 
      break; 
     } 

     case 2:{ //auto reference 
      for(int i=0; i<N;++i){ 
       high_resolution_clock::time_point t2 = high_resolution_clock::now(); 
       for(auto& temp : stuff){ 
        for(int jj=0; jj<N;++jj) 
         temp.work(); 
       } 
       duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 
       results_t3.push_back(time_span); 
       t1=t2; 
      } 
      break; 
     } 
     case 3:{ //reference 
      for(int i=0; i<N;++i){ 
       high_resolution_clock::time_point t2 = high_resolution_clock::now(); 
       for(int j=0; j<N;++j){ 
        my_struct & temp =stuff[j]; 
        for(int jj=0; jj<N;++jj) 
         temp.work(); 
       } 
       duration<double> time_span = duration_cast<duration<double>>(t2 - t1); 
       results_t4.push_back(time_span); 
       t1=t2; 
      } 
      break; 
     } 

    } 
} 
double temp=0; 
for(auto& t : results_t1){ 
temp+=t.count(); 
} 
temp=temp/N; 
std::cout << "pointer " << temp << " seconds."; 
std::cout << std::endl; 

temp=0.0; 
for(auto& t : results_t2){ 
temp+=t.count(); 
} 
temp=temp/N; 
std::cout << "direct " << temp << " seconds."; 
std::cout << std::endl; 

temp=0.0; 
for(auto& t : results_t3){ 
temp+=t.count(); 
} 
temp=temp/N; 
std::cout << "auto reference " << temp << " seconds."; 
std::cout << std::endl; 

    temp=0.0; 
for(auto& t : results_t4){ 
temp+=t.count(); 
} 
temp=temp/N; 
std::cout << "reference " << temp << " seconds."; 
std::cout << std::endl; 

cin.get(); 

return 0; 
} 
+0

좋은 대답이 필요한 경우에도 '최적화'를위한 태그. –

+0

@UchiaItachi 귀하의 의견은 최적화 질문 만 좋은 답변을 얻는다는 것을 의미하는 것 같습니다.) – Borgleader

+0

@Borgleader : 최적화 *에 대한 좋은 답변 *을 원하면 [태그 : 최적화]로 태그를 추가하는 것이 분명한 것 같습니다. –

답변

0

의 I는 각 방법에 대한 유사한 결과를 기대합니다. 시간은 루프에서 소비되지 않으며 수학 함수 sincos에 사용됩니다. 루프 불변량과 같은 컴파일러 최적화는 다른 루프만큼 빨리 case 1이 될 것이고 성능과 관련하여 다른 것들 사이에서 선택할 것은 없습니다.

스타일을 유지하려면 유지 관리를 돕고 장기적으로 버그를 줄이는 것이 바람직합니다. 나는 그 기초에 case 1 직접 액세스와 함께 갈 것입니다. 컴파일러를 돕기 위해 임시 파일을 사용하는 것은 실제로 컴파일러를 도와주지 않습니다.

+0

감사합니다. "컴파일러를 돕기 위해 임시 파일을 도입하는 것은 실제로 컴파일러를 돕지는 못합니다."기억할 수있는 아주 좋은 패러다임입니다. – darius

관련 문제