Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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
C 使用OpenMP的一个线程,串行执行比并行执行快_C_Multithreading_Openmp - Fatal编程技术网

C 使用OpenMP的一个线程,串行执行比并行执行快

C 使用OpenMP的一个线程,串行执行比并行执行快,c,multithreading,openmp,C,Multithreading,Openmp,我试图用数值积分的梯形规则来计算π的值。为此,我编写了一个串行代码,在给定范围内进行迭代。为了计算并行开销,我通过将线程数设置为1来运行相同的代码。现在,我得到了执行时间与问题大小的关系图 因为我们只创建了一个线程,所以我认为这不会带来太多的通信开销。那么,这背后的原因可能是什么呢?据我所知,指令的调用是在编译时完成的,也就是说,如果你定义了一个宏,那么它会在运行前被扩展,那么我是不是遗漏了什么?还是与我的想法完全不同 下面是序列码 #include<stdio.h> #includ

我试图用数值积分的梯形规则来计算π的值。为此,我编写了一个串行代码,在给定范围内进行迭代。为了计算并行开销,我通过将线程数设置为1来运行相同的代码。现在,我得到了执行时间与问题大小的关系图
因为我们只创建了一个线程,所以我认为这不会带来太多的通信开销。那么,这背后的原因可能是什么呢?据我所知,指令的调用是在编译时完成的,也就是说,如果你定义了一个宏,那么它会在运行前被扩展,那么我是不是遗漏了什么?还是与我的想法完全不同

下面是序列码

#include<stdio.h>
#include<omp.h>
int main()
{
    FILE *fp = fopen("pi_serial.txt", "a+");
    long num_steps = 1e9;
    double step_size = 1.0 / num_steps;
    long i;
    double sum = 0;
    double start_time = omp_get_wtime();
    for(i = 0; i< num_steps; i++) {
        double x = (i + 0.5) * step_size;
        sum += (4.0 / (1.0 + (x * x)));
    }
    sum = sum * step_size;
    double end_time = omp_get_wtime();
    fprintf(fp, "%lf %lf\n", sum, end_time - start_time);
    fclose(fp);
    return 0;
}   
#包括
#包括
int main()
{
文件*fp=fopen(“pi_serial.txt”,“a+”);
长步数=1e9;
双步大小=1.0/num步;
龙我;
双和=0;
双启动时间=omp\U get\U wtime();
对于(i=0;i
这是多线程代码

#include <stdio.h>
#include <omp.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    FILE* fp = fopen("pi_parallel.txt", "a+");
    omp_set_num_threads(1);
    long num_steps = atol(argv[1]);
    double step_size = 1.0 / num_steps;
    double sum = 0;
    double start_time = omp_get_wtime();
    #pragma omp parallel 
    {
        int id = omp_get_thread_num();
        double private_sum = 0;
        int i;
        for(i = id; i <= num_steps; i += 1){
            double x = (i + 0.5) * step_size;
            private_sum += (4.0 / (1.0 + x * x));
        }
        #pragma omp critical
            sum += private_sum;
    }
    sum *= step_size;
    double end_time = omp_get_wtime();
    fprintf(fp, "%lf %lf\n", sum, end_time - start_time);
    fclose(fp);
    return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
文件*fp=fopen(“pi_parallel.txt”,“a+”);
omp_设置_数量_线程(1);
long num_steps=atol(argv[1]);
双步大小=1.0/num步;
双和=0;
双启动时间=omp\U get\U wtime();
#pragma-omp并行
{
int id=omp_get_thread_num();
双私有_和=0;
int i;
对于(i=id;i

上面的视频将有助于理解为什么串行代码可能比具有一个线程的并行代码更快。 根据演示者可以看出,由于你正在设置OMP环境变量,在程序中间创建一个线程,OpenMP程序运行速度比串行代码慢。 但最主要的是看一下代码的可伸缩性——当在多个线程上运行时,与串行代码相比,代码的速度有多快? 当您在多个线程上运行相同的代码,仍然没有看到性能的提高时,可能是由于错误共享。从我理解的,考虑两个变量驻留在同一个高速缓存行中。主线程访问其中一个变量并修改它,使高速缓存行失效。如果线程1必须具有一个访问修改后的缓存线,然后将修改后的缓存线写入内存,然后线程从内存中提取缓存线并对其进行修改。此过程可能会增加执行时间

参考资料:


*我不拥有视频。

关键部分锁定开销?@AjayBrahmakshatriya但只有一个线程。我认为这不会发生(考虑信号量概念,信号量已初始化为1,线程不必等待更新结果)串行和并行代码在我的笔记本电脑上有相同的运行时。天真的问题:如何用一个线程并行执行某些东西?我想你只是为了线程安全而注入了代码(显然,执行起来需要一些时间)。OpenMP程序在一个线程上的串行执行通常比等效的串行程序慢。编译器可能无法像串行代码那样积极优化并行代码。然后在运行时,代码可能会因实例化OpenMP运行时工具而在启动性能上付出代价尽管代码只使用一个线程,但运行时事先并不知道这一点。随着时间的推移,仅链接的答案通常不会有用。您能否对此答案进行扩展,或者引用链接中的相关详细信息?