2013-05-18 5 views
1

Quelle est la méthode la meilleure et la plus efficace pour transmettre une grande quantité de données (nombres doubles) d'un programme FORTRAN à un programme C++? En ce moment j'utilise un fichier binaire mais ce n'est pas assez rapide!Transmettre une grande quantité de données de FORTRAN à C++

J'ai essayé le tuyau. J'ai suivi http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx pour la partie C++. Mais pour la partie FORTRAN (qui est le processeur de l'enfant), je ne sais pas comment écrire correctement les données. Dois-je écrire sur la console comme WRITE(*,*) AllTheNumbers? car écrire sur la console prend beaucoup de temps!

Mon code FORTRAN pour écrire des données:

 DO 281 I=1,NDOF 
     DO 280 J=1,UBW    
     IF (S(I,J).NE.0) THEN  
      WRITE (*, 2770) I,(J+I-1) 
      WRITE (*,2760) (S(I,J))   
     ENDIF   
280 CONTINUE   
281 CONTINUE 
+0

http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx –

+0

est-ce un tableau unidimensionnel de doubles? – EvilTeach

+0

J'ai inclus le tableau dans la question – VecTor

Répondre

4

Le moyen le plus rapide serait de faire un programme de langue mixte. Générez les nombres dans un (par exemple, Fortran) et appelez l'autre (par exemple, C++) à partir de ce langage. Avec la liaison ISO C de Fortran, l'appel C fait partie de la norme linguistique Fortran. De nombreux compilateurs Fortran supportent cela. Utilisez "extern C" du côté C++. Passer une série de doubles devrait être facile.

EDIT: si vous continuez à utiliser une méthode d'E/S pour transférer les informations, vous devez probablement transférer les informations sous la forme de données binaires. Vous échantillonnez le code Fortran en utilisant des E/S formatées ... la conversion de la représentation binaire interne des nombres en caractères lisibles par l'utilisateur est lente. Dans votre déclaration ouverte Fortran, utilisez: access='stream', form='unformatted'. N'utilisez pas un format sur l'écriture.

+0

Un programme C++ principal qui a l'interface appelle plusieurs programmes FORTRAN (en tant que processeurs enfants) et chacun d'eux produit un tableau de doubles. Je dois passer tous les tableaux au programme principal. Donc je ne peux pas les mélanger – VecTor

+0

On notera si c'est un tableau multidimensionnel, alors fortran et c stockent les tableaux différemment.Colonne/ligne pour fortran vs Ligne/colonne pour c – EvilTeach

+0

Il semble possible de les mélanger: C++ appelle Fortran sous-routine sub1 pour retourner array1, sub1 renvoie, puis C++ appelle Fortran sub2 pour retourner array2, sub2 renvoie, etc. Si vous avez besoin de plus speed, rend le programme C++ multithread, possède plusieurs tableaux et appelle les différents sous-programmes Fortran à partir de différents threads. –

1

L'utilisation d'un fichier binaire est probablement le plus lent possible. Ce problème a été rencontré avant:

https://en.wikipedia.org/wiki/Inter-process_communication

+0

Merci pour la réponse. J'ai aussi essayé le tuyau. J'ai suivi [http://msdn.microsoft.com/fr-CA/library/bb546102.aspx] pour la partie C++. Mais pour la partie FORTRAN je ne sais pas comment écrire correctement des données. Dois-je écrire sur la console? car écrire sur la console prend beaucoup de temps! – VecTor

1

Considérez la création de mémoire partagée. Le programme c le 'crée', écrit les données dedans et appelle le programme enfant fortran. Le programme fortran «mappe» la mémoire partagée, la traite et la quitte. Le programme c détruit alors la mémoire et quitte.

0

Une petite variante de la réponse ici: Write unformatted (binary data) to stdout, illustrant l'utilisation répétée d'un petit tampon.

real(kind=8) :: x(256) ! note real(kind=8) is "probably" an 8 byte float. 
          ! but not strictly guaranteed in fortran. 
    character(len=2048):: buffer ! 2048 == 256*8 
    do j=1,1000 
    do i = 1,256 
     x(i)=(i-1)**2+j*256 
    enddo 
    buffer=transfer(x,buffer) 
    write(*,'(a)',advance='no')buffer 
    enddo 
    end 

et le code python pour le lire, juste par exemple. (Struct module python fait plus agréable que C++ Je pense que pour le débogage de ces choses)

import subprocess 
import struct 
p=subprocess.Popen('./transfer',stdout=subprocess.PIPE) 
a=" " 
while a!="": 
a=p.stdout.read(8) 
if a!="" : print struct.unpack('d',a) 

Je ne l'ai jamais couru dans un problème avec « caractères non imprimables » lors de l'écriture comme celui-ci. Vous ne pouvez pas utiliser cette astuce pour lire depuis stdin dans fortran, mais en raison de chaînes de bits aléatoires interprétées comme EOF.

+0

@VecTor, je viens de vérifier cela fonctionne très bien sur un réseau avec Popen (['ssh', ..]). Bien sûr, vous devez vous soucier des problèmes d'ordre des octets dans ce cas. – agentp

Questions connexes