当前位置: 首页 > 知识库问答 >
问题:

使用private(num_threads)子句与default(无子句)的omp节

慕佑运
2023-03-14

我使用两个案例执行以下代码:

" $omp节"和"!$omp段私有(thread_num)"

在这两种情况下,每个部分都由不同的线程完成吗?

program main
use omp_lib
implicit none
integer, parameter:: ma=100, n=10000, mb= 100
real, dimension (ma,n) :: a 
real, dimension (n,mb) :: b
real, dimension (ma,mb) :: c = 0. 

integer:: i,j,k, threads=2, ppt, thread_num

integer:: toc, tic, rate 
real:: time_parallel, time 

call random_number (a) 
call random_number (b)

!/////////////////////// PARALLEL PRIVATE ///////////////////////
 c=0
CALL system_clock(count_rate=rate)
call system_clock(tic)

ppt = ma/threads
  !$ call omp_set_num_threads(threads)
  
  !$omp parallel

  !$omp sections private(thread_num)  !(HERE IS THE QUESTION TOPIC)

  ! EXAMPLE PROCESS 1 (it is only an example to test 'omp sections')
  !$omp section  
  !$ thread_num = omp_get_thread_num()
  !$ print*, "Section 1 started by thread number:", thread_num
  do i= 1,50
    do j= 1,mb
      do k= 1,n
        c(i,j) = c(i,j) + a(i,k)*b(k,j)
      end do 
    end do
  end do 
  !$ print*, "Section 1 finished by thread number:", thread_num

  ! EXAMPLE PROCESS 2
  !$omp section  
  !$ thread_num = omp_get_thread_num()
  !$ print*, "Section 2 started by thread number:", thread_num
  do i= 51,100
    do j= 1,mb
      do k= 1,n
        c(i,j) = c(i,j) + a(i,k)*b(k,j)
      end do 
    end do
  end do 
  !$ print*, "Section 2 finished by thread number:", thread_num

!$omp end sections
!$omp end parallel
print*, '//////////////////////////////////////////////////////////////'
print*, 'Result in Parallel' 
!$ print*, c(85:90,40)  
  
call system_clock(toc)
time_parallel = real(toc-tic)/real(rate)

!/////////////////////// normal execution ///////////////////////
 c = 0
CALL system_clock(count_rate=rate)
call system_clock(tic)

  call system_clock(tic)

  do i= 1,ma
    do j= 1,mb
      do k= 1,n
        c(i,j) = c(i,j) + a(i,k)*b(k,j)
      end do 
    end do
  end do 
  
  
call system_clock(toc)
time =  real(toc-tic)/real(rate)
print*, 'Result in serial mode'
print*, c(85:90,40)  
print*, '------------------------------------------------'
print*, 'Threads: ', threads, '|  Time Parallel ', time_parallel, 's '
print*, '                         Time Normal  ', time, 's'
!----------------------------------------------------------------

end program main

这分别是“!$omp sections”和“!$comp sections private(thread_num)”的结果:

第 1 节 按线程数开始:1

第2部分由线程号1开始

第1节按线程编号完成:1

第2节按Thread编号完成:1

//////////////////////////////////////////////////////////////

平行产生

2507.23853 2494.16162 2496.83960 2503.58960 2509.34448
2518.64160

串行模式下的结果

2507.23853 2494.16162 2496.83960 2503.58960 2509.34448
2518.64160

线程:2 |时间平行0.428116574

正常时间0.605000019秒

第1节由线程号0开始

第2部分由线程号1开始

第1部分由线程号0完成

第2节按Thread编号完成:1

//////////////////////////////////////////////////////////////

平行产生

2523.38281 2501.28369 2517.81860 2502.66235 2503.13940
2532.35791

串行模式下的结果

2523.38281 2501.28369 2517.81860 2502.66235 2503.13940
2532.35791

线程:2 |时间并行0.432999998

正常时间0.610204018 s

它是使用以下方法编译的:

Gfortranprog.exeprueba. f90.prog.exe

我笔记本电脑的CPU型号:

AMD A6-6310(4 核,每个核一个线程)

附言:主要目标是测试并行子句,而不是加速矩阵计算

共有1个答案

卫烨
2023-03-14

thread_num绝对应该是私有变量。否则两个线程都使用相同的变量,因此您可以从两个线程中获得值1。从两个线程写入同一个变量是一种竞争条件。

您可以将其设置为整个并行区域的私有区域,并且仅在区域开始时调用 omp_get_thread_num() 一次。

  !$omp parallel private(thread_num)

  !$ thread_num = omp_get_thread_num()

  !$omp sections 
  !$omp section
  !$ print*, "Section 1 started by thread number:", thread_num

  ...
 类似资料:
  • 问题内容: 有什么区别,每个应该有什么区别? 如果我正确理解该理论,则查询优化器应该可以互换使用。 问题答案: 它们不是同一件事。 考虑以下查询: 和 第一个将返回订单及其订单号的行(如果有)。第二个将返回所有订单,但只有订单将具有与之关联的任何行。 使用,子句 实际上是 等效的。但是,仅仅因为它们在功能上相同而产生相同的结果,并不意味着这两种子句具有相同的语义。

  • 我可以通过两种方式来实现这一点,使用where子句或join查询,在spark SQL中哪个更快?为什么?Where子句比较列添加、选择那些记录还是在列本身上联接,哪个更好?

  • 问题内容: 使用BETWEEN子句或使用<= AND> =比较之间在性能上有区别吗? 即这两个查询: …和 在此示例中,year列是带有索引的VARCHAR2(4)。 问题答案: 这两个示例查询之间没有性能差异,因为这只是表示 包含 范围比较的一种简便方法。Oracle解析条件时,它将自动扩展为单独的比较子句: 前任。 …将自动变为:

  • 如何使用hibernateTemplate执行批量更新操作。下面的代码抛出 原因:org。冬眠QueryParameterException:位置超出已声明序数参数的数量。请记住,序数参数是基于1的!职位:2 如何通过将用户列表作为参数传递来实现此批量更新操作???

  • 问题内容: 在WHERE子句中有使用SELECT语句描述的名称吗?这是好/不好的做法吗? 这会是更好的选择吗? 它远没有那么优雅,但是运行起来比以前的版本要快。我不喜欢它,因为它在GUI中没有非常清晰地显示(并且SQL初学者需要理解它)。我可以将其分为两个独立的查询,但是随后事情变得混乱了…… 注意:我不仅需要日期和分数(例如姓名) 问题答案: 称为相关子查询。它有它的用途。

  • 本文向大家介绍我们如何将MySQL DISTINCT子句与WHERE和LIMIT子句一起使用?,包括了我们如何将MySQL DISTINCT子句与WHERE和LIMIT子句一起使用?的使用技巧和注意事项,需要的朋友参考一下 通过在MySQL查询中将WHERE子句与DISTINCT子句一起使用,我们将基于一个条件,即MySQL返回结果集的唯一行。通过在MySQL查询中使用LIMIT子句和DISTIN