2.4. Sending and Receiving Stride-1 Data

PVMFPSEND(3) and PVMFPRECV(3) are send and receive routines that transfer either a single data item or stride-1 data to one PE. You do not have to initialize a send buffer or pack and unpack the data when you use PVMFPSEND and PVMFPRECV. For short messages, they run faster than the traditional send and receive routines, PVMFSEND and PVMFRECV.

The trade-off for the increase in speed is reduced flexibility. Using PVMFPSEND, you are limited to a single block of contiguous data, and it can be sent to just one other PE.

You are also limited to receiving a single block of contiguous data with PVMFPRECV. But, after PVMFPRECV completes, it is done with the message. Using PVMFRECV, one or more unpack calls may follow the PVMFRECV call, and information about the message must be kept around in case the user calls PVMFBUFINO(3). In both the send and the receive, the PVMFPSEND and PVMFPRECV routines offer much simpler and faster code.

The speedups from using PVMFPSEND and PVMFPRECV are most noticeable for small messages, meaning less than the value of the PVM_DATA_MAX environment variable (see Section 2.1). For large messages (greater than PVM_DATA_MAX), the performance benefits over PVMFSEND and PVMFRECV are not significant.

The following example shows a program that passes data by using the PVMFPSEND and PVMFPRECV routines. The SRC PE passes data to the DEST PE, which in turn passes it back to the SRC PE.


Example 2-2. PVMFPSEND and PVMFPRECV

1.        PROGRAM PSEND_PRECV
2.        INCLUDE 'fpvm3.h'
3.        INTEGER SRC, DEST
4.        PARAMETER(SRC = 0)
5.        PARAMETER(DEST = 1)
6.        PARAMETER(LEN = 10)
7.        PARAMETER(BACK_AND_FORTH = 1000)
8.        REAL ARRAY(LEN)
9.        INTRINSIC MY_PE
10.         
11.       ME = MY_PE()
12. C Initialize data
13.       IF (ME .EQ. SRC) THEN
14.          DO I = 1, LEN
15.            ARRAY(I) = I * 1.0
16.          ENDDO
17.       ENDIF
18. 
19. C Send and receive data BACK_AND_FORTH times
20.       DO I = 1, BACK_AND_FORTH
21. C Send data to DEST PE
22.         IF(ME .EQ. SRC) THEN
23.            CALL PVMFPSEND(DEST, LEN, ARRAY, LEN, REAL8,
24.      $                   ISEND)
25. C Receive data from DEST PE
26.            CALL PVMFPRECV(DEST, LEN, ARRAY, LEN, REAL8,
27.      $                   IATID, IATAG, IALEN, IRECV)
28.         ELSE
29. C Receive data from SRC PE
30.            CALL PVMFPRECV(SRC, LEN,  ARRAY, LEN, REAL8,
31.      $                   IATID, IATAG, IALEN, IRECV)
32. C Send data to SRC PE
33.            CALL PVMFPSEND(SRC, LEN, ARRAY, LEN, REAL8,
34.      $                   ISEND)
35.         ENDIF
36.       ENDDO
37.       END


The MY_PE function, define in line 9 and referenced in line 11, returns the number of the PE on which is executes. It is available on the CRAY T3E system as both an intrinsic and an external library routine. While the intrinsic is slightly faster, the library version is more portable. Unless you specifically declare MY_PE as an intrinsic, as in line 9, you will get the external library version. The same is true for the constant N$PES and the library equivalent NUM_PES. N$PES is slightly faster, but NUM_PES is more portable.