【OpenMP】入门

本文介绍OpenMP编程中计时、线程数量设置及环境变量调整的方法。通过实例演示如何使用omp_get_wtime()和omp_get_wtick()进行精确计时,如何通过omp_set_num_threads()设置线程数以充分利用多核处理器,以及如何解决多线程性能问题。同时探讨了多线程在不同CPU核心上的运行机制及缓存一致性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、计时

获取当前挂钟时间api : omp_get_wtime()

获取单个时钟周期的时长(s): omp_get_wtick()

#include "omp.h"
#include <stdio.h>
#include <unistd.h>

int main() {
    #获得当前挂钟时间
    double start = omp_get_wtime( );
    sleep(1);
    double end = omp_get_wtime( );
    printf("start = %.16g\nend = %.16g\ndiff = %.16g\n", start, end, end - start);

    //获得一个时钟周期是多少秒
    double wtick = omp_get_wtick( );
    printf("wtick = %.16g\n1/wtick = %.16g\n", wtick, 1.0 / wtick);
}

输出:

start = 72488773.2970518
end = 72488774.29709764
diff = 1.000045835971832
wtick = 1e-09
1/wtick = 999999999.9999999

可以看出单个时钟周期是10^-9秒,即一秒包括10亿个时钟周期。

2、设置使用线程数量

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

/*
 *  omp_set_num_threads()   设置使用线程数
 *  omp_get_num_threads()   获取使用多线程数量,如果在串行部分调用返回1,如果在并行部分调用,返回使用线程数
 *  omp_get_max_threads()   获取可以并行使用最多线程数
 *  omp_get_thread_num()    获取当前线程的ID
 *
 */
int main() {
    const int maxNumThreads = omp_get_max_threads();
    printf("Maximum number of threads for this machine: %i\n", maxNumThreads);

    printf("Not yet started a parallel Section: the number of threads is %i\n", omp_get_num_threads());

    printf("Setting the maximum number of threads...\n");
    omp_set_num_threads(maxNumThreads);

    printf("Once again, not yet started a parallel Section: the number of threads is still %i\n", omp_get_num_threads());

    printf("Starting a parallel Section...\n");

#pragma omp parallel for 
    for (int i = 0; i < maxNumThreads; i++) {
        int tid = omp_get_thread_num();
        printf("This is thread %i announcing that the number of launched threads is %i\n", tid, omp_get_num_threads());
    }

}

输出:

root@snisspreweb02 openmap]# ./003_num_thread 
Maximum number of threads for this machine: 16
Not yet started a parallel Section: the number of threads is 1
Setting the maximum number of threads...
Once again, not yet started a parallel Section: the number of threads is still 1
Starting a parallel Section...
This is thread 15 announcing that the number of launched threads is 16
This is thread 2 announcing that the number of launched threads is 16
This is thread 4 announcing that the number of launched threads is 16
This is thread 3 announcing that the number of launched threads is 16
This is thread 10 announcing that the number of launched threads is 16
This is thread 6 announcing that the number of launched threads is 16
This is thread 11 announcing that the number of launched threads is 16
This is thread 0 announcing that the number of launched threads is 16
This is thread 7 announcing that the number of launched threads is 16
This is thread 9 announcing that the number of launched threads is 16
This is thread 14 announcing that the number of launched threads is 16
This is thread 5 announcing that the number of launched threads is 16
This is thread 13 announcing that the number of launched threads is 16
This is thread 8 announcing that the number of launched threads is 16
This is thread 12 announcing that the number of launched threads is 16
This is thread 1 announcing that the number of launched threads is 16

3、如果OpenMP设置多线程后,速度反而比单线程慢了,需要设置以下环境变量:

export OMP_WAIT_POLICY=PASSIVE

4、进程的多个线程可以同时运行在多个CPU核心上吗?如果可以线程间共享的缓存怎么保存一致性?

是的,单个进程可以在不同的cpu核心上运行多个线程。

缓存具体来说指的是硬件。 许多现代的英特尔处理器都有三层缓存,一级缓存、二级缓存和内存,其中最后一级缓存在内核之间是共享的。

单个进程的多个线程运行在不同的CPU核心上,并不意味着非共享缓存是冗余的,但它确实对多核性能有影响。 特别是,如果一个CPU核心更新当前位于另一个核心的私有缓存中的地址空间中的值,则必须运行缓存一致性协议以确保另一个核心不会读取过时的值。

除了要求最快响应时间的关键系统外,通常不需要手工指定进程运行在多个CPU核心上。因为处理器分配的有效线程高度依赖于硬件,并且对同时运行的其他应用程序非常敏感。

如果要进行这样的实验,请创建一个长时间运行的CPU密集型任务,例如生成素数列表。然后创建两个线程,并在多处理器计算机上运行两个线程。这两个任务应该在大致相同的时间内完成,因为它们是并行运行的。

参考链接:https://stackoverflow.com/questions/38733670/can-a-single-process-run-in-multiple-cores

https://softwareengineering.stackexchange.com/questions/181157/how-to-program-thread-allocation-on-multicore-processors

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值