|
| View previous topic :: View next topic |
| Author |
Message |
stegan
Joined: 28 Oct 2004 Posts: 2
|
Posted: Thu Oct 28, 2004 12:36 am Post subject: Linking fortran and C code |
|
|
I'm using a fortran code (f90) for MonteCarlo calculations. During the execution the program uses a lot of times the intrinsic function "anint(x)" to get the integer value (returned as real) nearer to x.
I tried to use the same program, written in C, and the performance is better than fortran (about 30%). After some tests, I realized that the function "anint" in fortran is slower than the correspond "rint" in C; in fact if I don't use these functions in two programs, the fortran code is faster.
So, there is a solution to use the "rint" C function in the fortran code?
Thank's a lot. |
|
| Back to top |
|
 |
mkcolg
Joined: 30 Jun 2004 Posts: 4996 Location: The Portland Group Inc.
|
Posted: Thu Oct 28, 2004 12:32 pm Post subject: |
|
|
Chapter 10 of the PGI user's guide gives a good introduction to inter-language calling conventions. Basically, you need to create a C wrapper function which calls rint. Note the extra underscore after the function name and the use of pointer arguements. Also note that rint is a macro that complains if its compiled with pgcc, so you'll need to compile this file with gcc.
Example:
myrint.c
| Code: | #include <tgmath.h>
void myrint_ (float * val, float * rval) {
*rval = rint(*val);
} |
test.f
| Code: | program testing
real x,y
x = 123.1456
call myrint(x, y)
write(*,*), 'RINT(', x, ')=', y
y = 0.0
y = anint(x);
write(*,*), 'ANINT(', x, ')=', y
y = 0.0
x = 123.5678
call myrint(x, y)
write(*,*), 'RINT(', x, ')=', y
y = 0.0
y = anint(x);
write(*,*), 'ANINT(', x, ')=', y
end |
Command line:
| Code: | quartet:/tmp% gcc -c myrint.c
quartet:/tmp% pgf90 -c test.f
quartet:/tmp% pgf90 test.o myrint.o
quartet:/tmp% a.out
RINT( 123.1456 )= 123.0000
ANINT( 123.1456 )= 123.0000
RINT( 123.5678 )= 124.0000
ANINT( 123.5678 )= 124.0000
|
Let us know if this helps performance since I'm very curious why anint is so much slower.
- Mat |
|
| Back to top |
|
 |
stegan
Joined: 28 Oct 2004 Posts: 2
|
Posted: Thu Nov 04, 2004 9:38 am Post subject: |
|
|
Thank's for help!
I tried to do this, but the needed time for execution is longer.
In fact by using ANINT (in fortran), the required time is about 33% less than by using RINT (in C).
Probably the problem is another!
I ask you another question: why by declaring DOUBLE the myrint function is very and very slower than with FLOAT?
Thank's a lot.
Stefano |
|
| Back to top |
|
 |
mkcolg
Joined: 30 Jun 2004 Posts: 4996 Location: The Portland Group Inc.
|
Posted: Fri Nov 05, 2004 1:17 pm Post subject: |
|
|
Off hand I don't know why the double version is so much slower. When you compile the with "gcc -S" and view the generated assembly file the float version calls "rintf" and the double version calls "rint". My guess is that is simply takes more instructions to convert a double to and int than it does a float.
Have you tried compiling with a profiling flag and using the PGI profiler pgprof? This tool can really help in determining performance bottlenecks. A complete description of pgrof can be found in the PGI tools guide. http://www.pgroup.com/resources/docs.htm
- Mat |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2002 phpBB Group
|