Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使用C中的相同参数生成n个pthread的最有效方法_Multithreading_G++_Pthreads_Pthread Join - Fatal编程技术网

Multithreading 使用C中的相同参数生成n个pthread的最有效方法

Multithreading 使用C中的相同参数生成n个pthread的最有效方法,multithreading,g++,pthreads,pthread-join,Multithreading,G++,Pthreads,Pthread Join,我有32个线程,我提前知道输入参数,除了每个线程与之交互的内存缓冲区之外,函数内部没有任何变化 在伪C代码中,这是我的设计模式: // declare 32 pthreads as global variables void dispatch_32_threads() { for(int i=0; i < 32; i++) { pthread_create( &thread_id[i], NULL, thread_function, (void*) thread

我有32个线程,我提前知道输入参数,除了每个线程与之交互的内存缓冲区之外,函数内部没有任何变化

在伪C代码中,这是我的设计模式:

// declare 32 pthreads as global variables

void dispatch_32_threads() {
   for(int i=0; i < 32; i++) {
      pthread_create( &thread_id[i], NULL, thread_function, (void*) thread_params[i] );
   }
   // wait until all 32 threads are finished
   for(int j=0; j < 32; j++) {
      pthread_join( thread_id[j], NULL); 
   }
}

int main (crap) {

    //init 32 pthreads here

    for(int n = 0; n<4000; n++) {
        for(int x = 0; x<100< x++) {
            for(int y = 0; y<100< y++) {
                dispatch_32_threads();
                //modify buffers here
            }
        }
    }
}
我正在呼叫dispatch_32_threads 100*100*4000=40000000次。thread_函数和void*thread_参数[i]不会更改。我认为pthread_create一直在创建和销毁线程,我有32个内核,它们都没有达到100%的利用率,它徘徊在12%左右。此外,当我将线程数量减少到10个时,所有32个内核的利用率都保持在5-7%,并且在运行时没有看到任何减慢。运行少于10次会减慢速度

然而,运行1个线程的速度非常慢,所以多线程是有帮助的。我分析了我的代码,我知道thread_func的速度很慢,thread_func是可并行的。这让我相信pthread_create会在不同的内核上不断生成和销毁线程,在10个线程之后,我会失去效率,而且速度会变慢,thread_func本质上没有生成10个以上线程那么复杂


这个评估是真的吗?100%利用所有内核的最佳方法是什么?

线程创建成本很高。它取决于不同的参数,但很少低于1000次循环。线程同步和破坏是相似的。如果thread_函数中的工作量不是很高,那么它将在很大程度上控制计算时间

在内部循环中创建线程很少是个好主意。也许,最好是创建线程来处理外部循环的迭代。根据您的程序和thread_的功能,迭代之间可能存在依赖关系,这可能需要一些重写,但解决方案可能是:

int outer=4000;
int nthreads=32;
int perthread=outer/nthreads;

// add an integer with thread_id to thread_param struct
void thread_func(whatisrequired *thread_params){
  // runs perthread iteration of the loop beginning at start
    int start = thread_param->thread_id;
    for(int n = start; n<start+perthread; n++) {
        for(int x = 0; x<100< x++) {
            for(int y = 0; y<100< y++) {
                //do the work
            }
        }
    }
}

int main(){
   for(int i=0; i < 32; i++) {
      thread_params[i]->thread_id=i;
      pthread_create( &thread_id[i], NULL, thread_func, 
              (void*) thread_params[i]);
   }
   // wait until all 32 threads are finished
   for(int j=0; j < 32; j++) {
      pthread_join( thread_id[j], NULL); 
   }
}

使用这种并行化,可以考虑使用OpenMP。parallel for子句将使您能够轻松地试验最佳并行化方案

如果存在依赖项,并且这种明显的并行化是不可能的,那么您可以在程序启动时创建线程,并通过管理。管理队列的成本低于创建线程的成本,但原子访问确实有成本

编辑:或者,您可以 1.将所有循环放入线程函数中 2.在内部循环的开始或结束处,添加一个同步线程。这将确保所有线程都已完成其工作。 3.在主窗口中,创建所有线程并等待完成。
屏障比线程创建更便宜,结果也一样。

我不能这样移动循环,它不能以那种方式并行化。我唯一的选择是拥有一个线程池?有简单的方法吗?我需要一些非常简单的东西。