簡體   English   中英

為什么多線程更慢?

[英]Why is multithreading slower?

實現了使用歸並排序的1000000個節點的三個鏈表的多進程多線程實現。 我比較了實現程序的實時性,但是多線程的方式比較慢。 這是為什么?

進程中的主要方法。c

    /* Insert nodes */
    Node* tmp = NULL;   
    int num;    
    for( int i = 0; i < MAX; i++ )
    {
        fscanf(fread,"%d",&num);    
        tmp = createNode(num , i ); 
        insertNode( &list1.head, &list1.tail, tmp );
        tmp = createNode(num , i ); 
        insertNode( &list2.head, &list2.tail, tmp );    
        tmp = createNode(num , i );
        insertNode( &list3.head, &list3.tail, tmp );    
        tmp = createNode(num , i ); 
    }
    free( tmp );    
    fclose(fread);  

    if ((t1 = times(&mytms)) == -1) {
        perror("times 1");
        exit(1);
    }

    pid1= fork();   
    if(pid1==0){
        mergeSort( &list1.head );   
        file_output(&list1);    
        freeAll( list1.head );
        exit(1);    
    }
    pid2= fork();   
    if(pid2==0){
        mergeSort( &list2.head );   
        file_output(&list2);    
        freeAll( list2.head );  
        exit(2);    
    }
    pid3 = fork();
    if(pid3==0){
        mergeSort( &list3.head );   
        file_output(&list3);    
        freeAll( list3.head );  
        exit(3);    
    }

    wait(&status);  
    wait(&status);
    wait(&status);

    if ((t2 = times(&mytms)) == -1) {   
        perror("times 2");
        exit(1);
    }

    printf("Real time : %.5f sec\n", (double)(t2 - t1) / CLK_TCK);
    printf("User time : %.5f sec\n", (double)mytms.tms_utime / CLK_TCK);
    printf("System time : %.5f sec\n", (double)mytms.tms_stime / CLK_TCK);

實時結果:1.65

主線程.c

   /* Insert nodes */
   Node* tmp = NULL;   
   int num;           

   for( int i = 0; i < MAX; i++ )
   {
      fscanf(fread,"%d",&num); 
      tmp = createNode(num , i ); 
      insertNode( &list1.head, &list1.tail, tmp );  
      tmp = createNode(num , i );  
      insertNode( &list2.head, &list2.tail, tmp );  
      tmp = createNode(num , i );  
      insertNode( &list3.head, &list3.tail, tmp );  
   }

   free( tmp );
   fclose(fread);  

   if ((t1 = times(&mytms)) == -1) {
        perror("times 1");
        exit(1);
   }

   pthread_create( &t_id1, NULL, thread_func, &list1 );
   pthread_create( &t_id2, NULL, thread_func, &list2 );
   pthread_create( &t_id3, NULL, thread_func, &list3 );

   pthread_join( t_id1, (void*)&status );
   pthread_join( t_id2, (void*)&status );
   pthread_join( t_id3, (void*)&status );

   if ((t2 = times(&mytms)) == -1) {
        perror("times 2");
      exit(1);
   }

   printf("Real time : %.5f sec\n", (double)(t2 - t1) / CLK_TCK);
   printf("User time : %.5f sec\n", (double)mytms.tms_utime / CLK_TCK);  
   printf("System time : %.5f sec\n", (double)mytms.tms_stime / CLK_TCK);  

結果實時 2.27

為什么多線程更慢?

它是特定於處理器的,並且與內核數量、 CPU 緩存的組織、它們的緩存一致性、您的RAM相關。 另請參閱https://www.phoronix.com/上的測試和基准測試; 在 Intel Core i7 10700K 和 AMD Ryzen 9 3900X(價格接近)上不會一樣。

它也是編譯器優化特定的。 閱讀Dragon 的書和一本關於計算機體系結構的好書

它還取決於您的特定操作系統和特定的C 標准庫(例如GNU glibcmusl-libc不同),並且glibc 2.31同一台計算機上的性能可能與glibc 2.30不同。 閱讀高級 Linux 編程pthreads(7)nptl(7)numa(7)time(7)madvise(2)syscalls(2)

您是否嘗試過最近的 Linux 和最近的GCC 10至少調用gcc -Wall -O3 -mtune=native

您可以在 Linux 上使用proc(5)然后hwinfo來查詢您的硬件。

您可能對OpenCLOpenMPOpenACC感興趣,並且應該閱讀有關特定 C 編譯器的優化選項的信息。 對於最近的GCC ,請參閱 您甚至可以使用GCC 插件自定義您最近的 GCC 以改進優化,您可以嘗試最近的Clangicc編譯器。

另請參閱MILEPOST GCC項目和CTuning 一 另請閱讀這份報告草案 參加 ACM SIGPLANSIGOPS會議。 聯系您附近的計算機科學學者。

您可能可以在理解您的問題的答案的同時獲得博士學位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM