[英]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.