簡體   English   中英

在線程中調用時memcpy很慢

[英]memcpy slow when called in thread

我有一個memcpy的問題,我似乎不明白。 我在一個線程上使用memcpy,它比我從main運行時得到的時間慢3-4倍。 在這兩種情況下,我有2個線程正在運行一個正在等待,一個調用memcpy。 你能給我任何可能的解釋嗎? 我使用具有超線程的4核Intel機器。

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <pthread.h>
#include <algorithm>
#define MILLION 1000000

#define START_TIMER(timer) {          \
  gettimeofday(&(timer), NULL);           \
}

#define STOP_TIMER(timer) {         \
  gettimeofday(&(timer), NULL);         \
}

#define TIME_DIFF(timer1, timer2, total) {      \
  long long sec_diff = 0;         \
  long long usec_diff = 0;          \
  sec_diff = (timer2).tv_sec - (timer1).tv_sec;     \
  usec_diff = (timer2).tv_usec - (timer1).tv_usec;    \
  (total)+= (sec_diff * MILLION) + usec_diff;      \
}
void copy(){
    struct timeval start, stop;
    long long total=0;
    char buff[1024*1024];
    for(int i =0;i<100;i++){

    char* temp = new char[1024*1024];
    START_TIMER(start);
    std::copy(buff,buff+1024*1024,temp);
    STOP_TIMER(stop);
    TIME_DIFF(start,stop,total);
    delete temp;
    }
    printf("%lld\n",total/100 );
}
void* mem(void* args){
    copy();
    pthread_exit(NULL);
}

void * nothing(void *args){
    pthread_exit(NULL);

}
pthread_t thread;
int main(int argc,char* argv[]){
    if(atoi(argv[1])==0){
        pthread_create(&thread,NULL,nothing,NULL);
        pthread_join(thread,NULL);
        copy();
    }
    else{

        pthread_create(&thread,NULL,mem,NULL);
        pthread_join(thread,NULL);
    }
}

感謝您的時間。 我希望它不是太愚蠢。

一開始我無法運行代碼,當調用copy()時會發生線程(傳遞1作為參數)。 pthread_create分配一個小的堆棧大小,並聲明1MB陣列buff導致分段錯誤。

我改變了代碼,為線程分配了一個更大的堆棧:

int main(int argc,char* argv[]){
    if(atoi(argv[1])==0){
        pthread_create(&thread,NULL,nothing,NULL);
        pthread_join(thread,NULL);
        copy();
    }
    else{
        pthread_attr_t thread_attr;
        pthread_attr_init(&thread_attr);
        pthread_attr_setstacksize(&thread_attr , 20*1024*1024);
        pthread_create(&thread, &thread_attr,mem,NULL);
        pthread_join(thread,NULL);
    }
}

這是有效的,並且在我的機器上的任一線程上復制之間的運行時沒有區別。

但是,您的操作系統可能會導致堆爭用。 每次需要分配內存時,它需要控制“互斥”(某種類型,可能是spin_lock),以確保沒有其他線程正在從堆中分配/釋放。 這會導致您遇到的延遲。

調用'copy'函數時,進程的線程數似乎有所不同。 當從主線程調用它時,'nothing'線程已經退出,因此該進程只有一個線程。 但是當它從'mem'線程調用時,系統中實際上有兩個線程。 如果系統被加載或者進程的線程之間存在爭用,這可能會有所不同。 如果它在另一台機器或負載較少的機器上運行,則該時間差可能不存在。可以通過更改代碼來驗證此理論,以便您在無線程中等待並僅在調用復制函數后取消它。

暫無
暫無

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

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