在线程中调用时memcpy很慢

时间:2017-05-06 23:24:00

标签: c++ c multithreading pthreads memcpy

我有一个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);
    }
}

感谢您的时间。我希望这不是太愚蠢。

2 个答案:

答案 0 :(得分:0)

首先,我无法运行代码,当调用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);
    }
}

这样做,并且在我的机器上的任一线程上复制之间的运行时没有区别。

但是,您的操作系统可能会导致堆争用。每当它需要分配内存时,它需要控制一个互斥锁&#39; (某种,可能是spin_lock)确保没有其他线程从堆中分配/释放。这会导致您遇到的延迟。

答案 1 :(得分:0)

调用'copy'函数时,进程的线程数似乎有所不同。当从主线程调用它时,'nothing'线程已经退出,因此该进程只有一个线程。但是当它从'mem'线程调用时,系统中实际上有两个线程。如果系统被加载或者进程的线程之间存在争用,这可能会有所不同。如果它在另一台机器或负载较少的机器上运行,则该时间差可能不存在。可以通过更改代码来验证此理论,以便您在无线程中等待并仅在调用复制函数后取消它。