Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29246 Discussions

OpenMP task consuming cpu after completion

Jose_Antonio_Martin
396 Views

Hello

I've been developing a GUI from scratch using Fortran together with some C libraries (mainly OpenGL to draw the widgets). I know that there are many better alternatives for GUI generation and that I am reinventing the wheel, but I thought that it was a good exercise to learn all the object oriented features introduced with the Fortran 2003 standard which were quite new for me.

The point is that I already have something quite acceptable working and I wanted to improve it by making the GUI responsive while running long processes. For this purpose I have used the OpenMP tasks construct, and it works. However, the problem is that the threads involved in the task execution remain active consuming 100% of the CPU after the task completion.

I have tried setting the OMP_WAIT_POLICY variable to PASSIVE and KMP_BLOCKTIME to 0 but it does not solve the issue.

I know that OpenMP is not designed for this purpose but I thought that thanks to the task constructs it would be possible to use it and take advantage of its portability. However having the processors running at 100% while they should be idle waiting for new jobs is not acceptable.

Before moving to other alternatives I would like to know from the experts if I am doing something wrong with it or if I could rearrange the program somehow to avoid this behavior.

I am attaching a simplified code to reproduce the issue.

Thanks in advance!

 

module common_data

character(len=500) :: my_completed_tasks = ""

end module common_data


module my_routines
  use common_data
  use omp_lib
  implicit none

  contains

  subroutine run_task(name)
    character(len=1), intent(in) :: name

    print*, "Before task creation : thread id: ", omp_get_thread_num(), "/", omp_get_num_threads()
!$omp task shared(my_completed_tasks)
    print*, "Starting task ", name
    print*, "During task execution... thread id: ", omp_get_thread_num(), "/", omp_get_num_threads()
    call sleepqq(5000)
    my_completed_tasks = trim(my_completed_tasks)//" "//name
    print*, "Task ", name, " completed"
!$omp end task
    print*, "After task creation: thread id: ", omp_get_thread_num(), "/", omp_get_num_threads()

  end subroutine

end module my_routines


program multitask

use common_data
use my_routines
implicit none
character(len=1) :: key
integer :: i

key = ""
i = 1

!create a team of threads using OpenMP to allow the parallel run of tasks in the background
!$omp parallel

!the main loop is executed by the master thread (mainly to use always the same thread for OpenGL operations)
!$omp master
do while (key.ne."q")

  ! { ... } gui related code and event processing

  write(*,"(a,i3,a)", advance="no") "iter ", i, "  > "
  read(*,*) key

  !if an event fires a cpu consuming computation, launch a task that will be executed by other thread keeping the responsiveness of the gui
  call run_task(key)

  i = i + 1
  print*, "Completed tasks: ", trim(my_completed_tasks)

end do
!$omp end master
!$omp end parallel

end program multitask

 

 

 

0 Kudos
0 Replies
Reply