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

POSIX tutorial

dondilworth
New Contributor II
4,167 Views

Today I'm looking into the POSIX routines, hoping to get multi-processor efficiency.  I have the standard documentation for all the library and function calls, but for a beginner I still have a zillion questions.  Can anyone point me to a good tutorial on the subject?  I'd hate to pester experts with dumb (to them) questions.

DD

0 Kudos
26 Replies
Steven_L_Intel1
Employee
3,196 Views

Are you referring to the POSIX thread routines? I'm not aware of a tutorial on those. Use of OpenMP is more popular, or you could try using the compiler's autoparallel feature.

0 Kudos
dondilworth
New Contributor II
3,196 Views

Steve:

I already use OpenMP, and for some tasks it's great.  But now I'm working on a feature that really requires multiprocesses, not multithreads.  I found the list of POSIX Library Procedures, and it has lots of features.  But, for example, how do I arrange for separate processes to share a block of memory -- for updating data that each should know about?  A tutorial would be very helpful here.  Can you point me to one?

DD

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,196 Views

You might want to look at MPI (Message Passing Interface). Intel has a version of MPI (http://software.intel.com/en-us/intel-mpi-library) and there are other open source versions of MPI (start with http://www.open-mpi.org/)

Jim Dempsey

0 Kudos
dondilworth
New Contributor II
3,196 Views

Well, that's a step forward -- but it seems like overkill.  I only need to read and change the values in an array of 10 real numbers.  That may be possible using PXFSTRUCTCREATE....  Is there a more direct way you can recommend?

DD

0 Kudos
dondilworth
New Contributor II
3,196 Views

Now I'm in real trouble.  I cannot get PXFPIPE, PXFFORK, or PXFWAIT to link.  Here are my declarations:

    USE IFPOSIX
...

    INTEGER(4) IPID,ISTAT,IERROR,IPID_RET,ISTAT_RET,IREADFD,IWRITEFD,JHANDLE

        CALL PXFPIPE(IREADFD,IWRITEFD,IERROR)    ! CREATE PIPE FOR SENDING DATA

        CALL PXFFORK(IPID,IERROR)        ! FORK NEW PROCESS HERE
            CALL PXFWAIT(ISTAT,IPID_RET,IERROR)

Error    11    error LNK2019: unresolved external symbol _PXFPIPE@12 referenced in function _DSEARCH    C:\SYNOPSYSV14\SYNOPSYS200_lib_.lib(Automf.obj)    SYNOPSYS200
Error    12    error LNK2019: unresolved external symbol _PXFFORK@8 referenced in function _DSEARCH    C:\SYNOPSYSV14\SYNOPSYS200_lib_.lib(Automf.obj)    SYNOPSYS200
Error    13    error LNK2019: unresolved external symbol _PXFWAIT@12 referenced in function _DSEARCH    C:\SYNOPSYSV14\SYNOPSYS200_lib_.lib(Automf.obj)    SYNOPSYS200

What's going on?

DD


0 Kudos
Steven_L_Intel1
Employee
3,196 Views

Do you have the CVF calling mechanism option set? Turn it off.

0 Kudos
dondilworth
New Contributor II
3,196 Views

Yes.  I have /iface:cvf turned on.  Have to, or nothing works.  This is a huge project ported from CVF.  Is there any way to rewrite the calls so they work in my case?

DD

0 Kudos
Steven_L_Intel1
Employee
3,196 Views

Oh, I see. The routines you want to use aren't supported on Windows. Sorry.

 I see the documentation doesn't mention that they are Linux/OS X only. I will ask that this be corrected.

You could use Windows API threads.

0 Kudos
mecej4
Honored Contributor III
3,196 Views
There is a Posix Pthreads library available for use with MSVC/Intel-C, but it has, obviously, a CDECL interface. DD will have to weigh the costs of writing interfaces to these for use from Fortran. If any callback functions are going to be passed to the Posix routines, they will have to be CDECL as well. Pthreads Library for MSVC
0 Kudos
dondilworth
New Contributor II
3,196 Views

Ugggh... this doesn't look good.  Thanks, everyone, for clearing up the fog.  I'll study the API approach.  Grrrr.

DD

0 Kudos
mecej4
Honored Contributor III
3,196 Views

Do you really wish to develop, in the year 2013, code tied to STDCALL conventions? Have you noted that if, down the road, you wish to move to x64 code, you will have to redo much of what you are now doing?

Writing to the Pthreads API will give you better portability to Linux. Writing to the Windows threads API will let you target 32- or 64-bit Windows only, but may give you slightly better performance than with Pthreads.

0 Kudos
Steven_L_Intel1
Employee
3,196 Views

The documentation does indicate that PXFFORK and PXFWAIT are supported on Linux and OS X only. But PXFPIPE is not so noted. I also found PXFLINK and PXFSIGACTION missing this notation. I have found some other errors in the POSIX routine documenattion and have notified our writers.

0 Kudos
dondilworth
New Contributor II
3,196 Views

mecej4 wrote:

Do you really wish to develop, in the year 2013, code tied to STDCALL conventions? Have you noted that if, down the road, you wish to move to x64 code, you will have to redo much of what you are now doing?

Writing to the Pthreads API will give you better portability to Linux. Writing to the Windows threads API will let you target 32- or 64-bit Windows only, but may give you slightly better performance than with Pthreads.

Thank you for your cogent question, mecej4 -- and if I were starting today I would certainly use modern tools and protocols.  But what would you do if you were maintaining and developing a huge code that started in 1962, first on vacuum tubes, and over the years migrated to Honeywell mainframes, IBM minicomputers, CDC mainframes, Unix, DOS, and then Windows about 15 years ago?  Would you re-write thousands of subroutines, weeding out all the legacy code and obsolete calling conventions?  The program works as it is now, and any major overhaul would take months of effort and would introduce countless new bugs.  It ain't broke, so I don't want to fix it.

But I do want to enhance the speed by a factor of 2 to 10, and this requires farming out a group of very time-consuming calculations to separate processes.  Logically it would be quite simple.  But Windows apparently does not support the fork() feature found on Unix.  I was hoping there was an efficient way to do just that.  Looks like there isn't.  Oh, well.  Thank you for the comment, anyway.

DD

0 Kudos
dondilworth
New Contributor II
3,196 Views

Today I have interesting results.  Since there is no fork() option on Win32, I  tried the spawnl() function in C++ instead, called by a Fortran routine.  It works, the new process starts, and I send a command argument that tells the new process to look in a named file for all of the initializations that it needs in order to start up where the parent process did the spawn.  It's not all that much work, and it runs just fine.  Most of the time.

And there's the rub.  The processes call many subroutines, some of which read and write disk files, and if it ever happens that two processes want the same access at the same time, I either get a crash or incorrect data.  So .... Is there any way you can think of whereby I can tell a process to wait for a few milliseconds because a different process is accessing a resource?  Since there is no PIPE in my emulation, it's hard to implement inter-process communication.

Any ideas?

DD

0 Kudos
Steven_L_Intel1
Employee
3,196 Views

You probably need to add mutexes to synchronize access to the files. Windows treatment of shared ordinary files isn't all that good. You may also want to consider the use of a shared global variable in a DLL - see the sample DLL_Shared_Data for ideas.

0 Kudos
mecej4
Honored Contributor III
3,196 Views

DonDilworth wrote:
Is there any way you can think of whereby I can tell a process to wait for a few milliseconds...
There are various "sleep.." functions available, but I doubt that you should think in terms of time rather than a sequence of events that should occur. You can use mutexes, semaphores, etc., as Steve already suggested. Another way, which is simpler,  if it can be used  in your application, is to have the main thread make all decisions as to when to read or write files and calling other threads.

0 Kudos
dondilworth
New Contributor II
3,196 Views

Remember, these are not threads, they are different processes.  So the tools are different.

Here's an idea I am trying now:  Subroutine A wants to open and read from file 23.  Subroutine B may have that open at the moment.  So in A, I have

10      CLOSE (23,ERR=10)

        OPEN (23)

        (Use this file)

        CLOSE(23)...

If the file is currently open in a different process, the first CLOSE will fail.  So it keeps trying until it works (subroutine B closes it when finished).  Is there anything wrong with this trick?

0 Kudos
mecej4
Honored Contributor III
3,196 Views

DonDilworth wrote:
10      CLOSE (23,ERR=10)
This is, in effect, a "polling loop". Depending upon what else is going on on the computer on which this statement is part of just one process, it could eat up lots of CPU time with little output for the resources consumed. There are many discussions available concerning the tradeoffs between interrupt (or event) driven I/O versus program loop I/O.

0 Kudos
dondilworth
New Contributor II
3,196 Views

The tradeoff here is pretty simple: most of the cores are idle most of the time.  I spawn to some cores to do a job that might run for an hour.  If a given core has to spin for a few milliseconds now and then, it's not an issue.  And the code is very simple.

But now I have a new question:  in my spawn() call, I need the full path to the exe code.  Is there any way for the program to know what that path is?  I don't want to hard-code it, since installations can vary.  What kind of system calls will tell me that path?

0 Kudos
mecej4
Honored Contributor III
3,010 Views

See the example code in the entry for COMMAND_ARGUMENT_COUNT in the Intel Fortran reference manual. If the executable is run by double clicking its icon from Windows Explorer, you will get the drive, path and name of the EXE file displayed. If it is run from CMD.EXE, you may need to call GETENV to obtain PATH, and see where along PATH the EXE exists (its name was returned by GET_COMMAND_ARGUMENT).

0 Kudos
Reply