2012-12-02 2 views
0

멀티 스레딩 (이전의 경험 없음)으로 플레이하고 int main에서 2 개의 별도 스레드를 통해 호출되는 간단한 함수를 가지고 있습니다.이 함수는 2에서 변수를 변경 (및 생성)합니다. 루프. 내가 말할 수있는 한 두 스레드간에 종속성은 없지만 하나의 스레드가 내 타이밍을 실행하는 것은 2.29 초이고 두 개는 7.11 초 (3 ~ 4 초 정도를 기대할 것입니다)입니다.간단한 절차로 느린 멀티 스레딩

두 개의 Intel atom CPU (Ubuntu 10.04)를 사용하는 netbook에서 실행 중입니다. int main() 프로세스 자체가 스레드를 포함하고 있기 때문에 어느 스레드도 단일 CPU의 "소유권"을 얻지 못합니다. 어떤 OS가 필요하든간에) 성능에 치명타를 쳤습니다. (아마도 스레드 전환!)

여기서 개선 할 수있는 방법이 있습니까? (아마 쓰레드 사이를 뛰어 넘기 위해 CPU가해야하는 작업을 줄일 수 있습니다). 나는 약간의 고기를 더 빨리 처리하기를 희망하고있다. (다른 스레드가 다른 스포크를 소유하고있는 휠 분해 인자를 사용하는 프라임 체를 사용한다.) 나는 지금 당장 얻고있는 성능에 너무 감동하지 않는다.

내가 지금 가지고있는 간단한 코드 다음과 같다 :

#include <iostream>" 
#include <ctime> 
#include <pthread.h> 


void* foo(void* dummyVar) 
{ 
    for(int i=1; i < 10; i++) 
    { 
     for(int j=1; j < 50000000; j++) 
     { 
      int test = j; 
     } 
      std::cout << i << "\n"; 
    } 
    pthread_exit(NULL); 
} 

int main(int argc, const char *argv[]) 
{ 
    clock_t start = clock(); 
    pthread_t thread1; 
    pthread_t thread2; 
    pthread_attr_t attribute; 
    void* status; 
    pthread_attr_init(&attribute); 
    pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_JOINABLE); 
    int i = 0; 
    int b = pthread_create(&thread1, NULL, foo, (void*)i); 
    int c = pthread_create(&thread2, NULL, foo, (void*)i); 
    pthread_join(thread1, &status); 
    pthread_join(thread2, &status); 

    std::cout << ((double)clock() - start)/CLOCKS_PER_SEC << "\n"; 
    return 0; 
} 

업데이트 : 나는 더 나은 성능을 얻으려면, 다른 한 스레드는 foo는 (대신 두 개의 스레드)를 호출 한 후 주() 호출 foo에 관련된 스레드를 가지고함으로써, 멀티 스레딩 불구하고 (당연히!) 이 기계에서 여전히 더 느립니다 (foo에 약간의 변경을가 했음 - 지금은 단지 하나의 루프를 위해 - 타이밍은 5.17 vs 6.01 임)

+1

너무 원시/수명이 짧은 작업은 실제 이점보다 높은 스레드 전환 오버 헤드를 초래할 수 있습니다. –

+1

당신의 경우에는 스레드의 수가 하드웨어 가용성, 즉 1 점 이상이라는 것을 말하고 있습니다. 또한 스레드는 무시할 수있는 I/O를 수행하여 대부분의 시간 동안 바쁘게 유지하므로 자신과 스레드 사이에 더 많은 경쟁이 있습니다 나쁜 성능을 제공합니다. –

+0

나는 ... 두 주석에 대한 감사의 말을 여기에있다 - 나는이 기계 (바퀴를 8 개의 스포크로 체포 함)에서 미래를 계획 한 멀티 스레딩이 비슷한 운명에 처할 확률이 높다는 말을하는 것이 옳은가? 프라임 인디케이터 배열에서 1을 뒤집는 루프 (시작점을 얻기위한 작은 함수 사용)는 상당히 사소 할 것입니다. - 아직 코딩하지 않았지만 루프 당 5 개 이상의 명령어가 있다는 것을 볼 수 없습니다. (그리고 스포크 사이에서 점프) – HexedAgain

답변

2
for(int j=1; j < 50000000; j++) 
    { 
     int test = j; 
    } 

적절한 벤치 마크는 미술 일 수 있지만, 이것은 빠르게 넘어집니다. 이 코드를 생존시키는 유일한 방법은 최적화 프로그램을 켜는 것을 잊는 것입니다. 어떤 괜찮은 컴파일러에서도 유용한 부작용이 없으므로 루프를 완전히 제거합니다.

실제로 10 배

std::cout << i << "\n"; 

동시에 실행할 수 없다 성명을 측정하고, 실제로 최적화를 설정 한 가정하면, 스레드는 터미널/콘솔에 대한 액세스를 직렬화 잠금 놓고 싸우는 것입니다. 기대되는 결과로 이것은 실제로 느려질 것입니다.

하지만 옵티 마이저를 잊어 버렸을 확률은 높지 만 켜져 있지 않은 프로필 코드는 절대 포기하지 않으므로 그렇게하지 마십시오.

+0

Aha! 그걸 지적 해 주셔서 대단히 감사합니다. 컴파일러가 최적화 플래그를 설정하면 컴파일러는 확실히 루프를 죽이지 않을 것입니다 (예, 잊어 버렸습니다!) - 더 이상 플레이하지 않고 foo 외부의 정적 변수를 J + i의 값으로 설정합니다 ((적어도이 경우에는) 최적화하지 않은 부작용과 std :: commentout을 주석 처리했습니다. 이제 멀티 스레딩이 다음과 같이 약간 승리합니다. 1.18 vs 1.21 – HexedAgain