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

Choose Only One Processor to Run

zhao__robert
Beginner
633 Views

Dear all,

I am using IVF 18 with Visual Studio 2017. The desktop has two CPUs, E5-2630 V4*2

Each CPU has 20 threads.

Two questions: 

1. How can I run my code only on the first CPU (or one of them)?

2. The second CPU was recently installed (With a new memory stick as well). Why the code run slower than the previous case with only one CPU?

Each worker in the parallel procedure keep a large private copy of several large multi-dimensional arrays. Can this be the reason?

Here is the optimization parameters I use

/nologo /MP /O3 /QxHost /Qparallel /Qpar-threshold:85 /Qvec-threshold:85 /Qopt-prefetch=2 /Qipo /Qopenmp /module:"x64\Release\\" /object:"x64\Release\\" /Fd"x64\Release\vc150.pdb" /libs:static /threads /c

 

Thanks a lot.

 

Robert

0 Kudos
1 Reply
JVanB
Valued Contributor II
633 Views

There is SetProcessAffinityMask to restrict the current process to a subset of processors. If there are more than 64 processors you may need some of the functions discussed in https://msdn.microsoft.com/en-us/library/windows/desktop/dd405527(v=vs.85).aspx to handle the processor group. Those functions don't seem to be in my old version of kernel32.mod, but it's easy enough to write out interfaces for the ones that are needed. Here is a sample program that finds the current thread's processor affinity and the current process' affinity and restricts it to the even-indexed processors.

module M
   use IFWIN
   implicit none
   type, bind(C) :: T_GROUP_AFFINITY
      integer(HANDLE) Mask
      integer(WORD) Group
      integer(WORD) Reserved(3)
   end type T_GROUP_AFFINITY
   interface
      function GetProcessGroupAffinity(hProcess,GroupCount, &
         GroupArray) bind(C,name='GetProcessGroupAffinity')
         import
         implicit none
!DEC$ ATTRIBUTES STDCALL :: GetProcessGroupAffinity
         integer(BOOL) GetProcessGroupAffinity
         integer(HANDLE), value :: hProcess
         integer(SHORT) GroupCount
         integer(SHORT) GroupArray(*)
      end function GetProcessGroupAffinity
      function GetMaximumProcessorGroupCount() &
         bind(C,name='GetMaximumProcessorGroupCount')
         import
         implicit none
!DEC$ ATTRIBUTES STDCALL :: GetMaximumProcessorGroupCount
         integer(WORD) GetMaximumProcessorGroupCount
      end function GetMaximumProcessorGroupCount
      function GetThreadGroupAffinity(hThread,GroupAffinity) &
         bind(C,name='GetThreadGroupAffinity')
         import
         implicit none
!DEC$ ATTRIBUTES STDCALL :: GetThreadGroupAffinity
         integer(BOOL) GetThreadGroupAffinity
         integer(HANDLE), value :: hThread
         type(T_GROUP_AFFINITY) GroupAffinity
      end function GetThreadGroupAffinity
   end interface
end module M

program P
   use M
   implicit none
   integer(HANDLE) hProcess
   integer(BOOL) res32
   integer(SHORT) GroupCount
   integer(SHORT), pointer :: GroupArray(:)
   integer(DWORD) LastError
   integer i
   integer(WORD) MaxGroup
   type(T_GROUP_AFFINITY) GroupAffinity
   integer(HANDLE) hThread
   integer(HANDLE) ProcessAffinityMask,SystemAffinityMask

   hProcess = GetCurrentProcess()
   write(*,'(a,Z16.16)') 'hProcess = ',hProcess
   GroupCount = 0
   nullify(GroupArray)
   res32 = GetProcessGroupAffinity(hProcess,GroupCount,GroupArray)
   if(res32 /= 0) then
      LastError = GetLastError()
      if(LastError == ERROR_INSUFFICIENT_BUFFER) then
         write(*,'(*(g0))') 'Required buffer size = ',GroupCount
         allocate(GroupArray(GroupCount))
         res32 = GetProcessGroupAffinity(hProcess,GroupCount,GroupArray)
         write(*,'(a)') 'Group Number'
         do i = 1, GroupCount
            write(*,'(i5,1x,i6)') i, GroupArray(i)
         end do
      else
         write(*,'(*(g0))') 'Unknown error = ',LastError,' from GetProcessGroupAffinity'
         stop
      end if
   else
      write(*,'(*(g0))') 'Unexpected success of GetProcessGroupAffinity'
   end if
   MaxGroup = GetMaximumProcessorGroupCount()
   write(*,'(*(g0))') 'Max Groups = ',MaxGroup
   hThread = GetCurrentThread()
   write(*,'(a,Z16.16)') 'hThread = ',hThread
   res32 = GetThreadGroupAffinity(hThread,GroupAffinity)
   write(*,'(i4,6(i10))') (i,i=6,0,-1)
   write(*,'(*(g0))') '3210',('9876543210',i=1,6)
   write(*,'(B64.64)') GroupAffinity%Mask
   write(*,'(*(g0))') 'Group = ',GroupAffinity%Group
   res32 = GetProcessAffinityMask(hProcess,ProcessAffinityMask,SystemAffinityMask)
   write(*,'(i4,6(i10))') (i,i=6,0,-1)
   write(*,'(*(g0))') '3210',('9876543210',i=1,6)
   write(*,'(B64.64)') ProcessAffinityMask
   res32 = SetProcessAffinityMask(hProcess,IAND(ProcessAffinityMask, &
      int(Z'5555555555555555',HANDLE)))
   res32 = GetProcessAffinityMask(hProcess,ProcessAffinityMask,SystemAffinityMask)
   write(*,'(i4,6(i10))') (i,i=6,0,-1)
   write(*,'(*(g0))') '3210',('9876543210',i=1,6)
   write(*,'(B64.64)') ProcessAffinityMask
end program P

Output on my machine was:

hProcess = FFFFFFFFFFFFFFFF
Unexpected success of GetProcessGroupAffinity
Max Groups = 1
hThread = FFFFFFFFFFFFFFFE
   6         5         4         3         2         1         0
3210987654321098765432109876543210987654321098765432109876543210
0000000000000000000000000000000000000000000000000000000011111111
Group = 0
   6         5         4         3         2         1         0
3210987654321098765432109876543210987654321098765432109876543210
0000000000000000000000000000000000000000000000000000000011111111
   6         5         4         3         2         1         0
3210987654321098765432109876543210987654321098765432109876543210
0000000000000000000000000000000000000000000000000000000001010101

I am pretty sure the results will differ on your machine.

P.S. I have noticed that many avatars have gone away again and when I tried to update mine, the upload button on my dashboard page didn't seem to do anything useful. Another forum bug?

 

0 Kudos
Reply