我最近来维护大量的科学计算密集型FORTRAN代码。 尽pipe有谷歌和两本入门级别的书籍,但我仍然无法处理所有40年语言的细微差别。 代码充斥着“性能增强的改进”。 有没有人有任何指导或实用的build议去优化FORTRAN到CS 101的水平? 有没有人知道如何运行FORTRAN代码优化? 是否有任何典型的FORTRAN'gotchas'可能不会出现在Java / C ++ /。NET高级开发人员接pipeFORTRAN 77/90的代码库?
出于好奇,我决定将自己的matrix乘法函数与BLAS实现进行比较…我最不感到惊讶的结果是: 自定义实现,10个1000x1000matrix乘法的试验: Took: 15.76542 seconds. BLAS实施,1000×1000matrix乘法的10次试验: Took: 1.32432 seconds. 这是使用单精度浮点数。 我的实施: template<class ValT> void mmult(const ValT* A, int ADim1, int ADim2, const ValT* B, int BDim1, int BDim2, ValT* C) { if ( ADim2!=BDim1 ) throw std::runtime_error("Error sizes off"); memset((void*)C,0,sizeof(ValT)*ADim1*BDim2); int cc2,cc1,cr1; for ( cc2=0 ; cc2<BDim2 ; ++cc2 ) for ( cc1=0 ; cc1<ADim2 […]
我从一个模拟(用Fortran编写)得到一个表示温度分布的512 ^ 3数组。 该数组存储在大小约为1 / 2G的二进制文件中。 我需要知道这个数组的最小值,最大值和平均值,因为无论如何,我将很快需要了解Fortran代码,所以我决定给它一个提示,并提出以下非常简单的例程。 integer gridsize,unit,j real mini,maxi double precision mean gridsize=512 unit=40 open(unit=unit,file='T.out',status='old',access='stream',& form='unformatted',action='read') read(unit=unit) tmp mini=tmp maxi=tmp mean=tmp do j=2,gridsize**3 read(unit=unit) tmp if(tmp>maxi)then maxi=tmp elseif(tmp<mini)then mini=tmp end if mean=mean+tmp end do mean=mean/gridsize**3 close(unit=unit) 这在我使用的机器上每个文件需要约25秒。 这让我感到相当长,所以我继续前进,在Python中做了以下事情: import numpy mmap=numpy.memmap('T.out',dtype='float32',mode='r',offset=4,\ shape=(512,512,512),order='F') mini=numpy.amin(mmap) maxi=numpy.amax(mmap) mean=numpy.mean(mmap) 现在,我认为这当然会更快,但是我真的被吹走了。 在相同的条件下需要不到一秒的时间。 平均数偏离我的Fortran例程发现的数据(我也用128位浮点数运行,所以我以某种方式相信它),但是仅在第7位有效数字左右。 numpy怎么能这么快? 我的意思是你必须看看数组的每一个条目来find这些值,对吧? 我在Fortran程序中做了一些非常愚蠢的事情,因为它需要更长的时间? 编辑: 要回答评论中的问题: […]
任何人都可以提供良好的CMake教程的链接,除非非常昂贵和难以获得的官方吗? 在使用CMake for Fortran项目时特别有趣,但对任何好的教程都会感激。 更新。 我已经find的是Kitware Public Wiki中的CMake文章 。 Fortran的例子是绝对没用的。 =(同样在等待答案时,我正在玩SCons ,看起来不错=)
我不时读到Fortran是或可以比C更快的计算。 这是真的吗? 我必须承认,我几乎不了解Fortran,但是到目前为止我看到的Fortran代码并没有表明这个语言具有C没有的特性。 如果是这样,请告诉我为什么。 请不要告诉我什么语言或库对数字处理有好处,我不打算写一个应用程序或库来做到这一点,我只是好奇。
我正试图从C调用一个FORTRAN函数 我的问题是: 如果fortRoutine是我的fortran子程序的名字,那么我从C调用它作为fortRoutine_ 。 如果fortRoutine只包含一个字符数组参数,那么我可以像这样传递: fortRoutine_("I am in fortran"); 在调用FORTRAN子程序的时候,我应该何时使用按值传递,何时传递参考? 因为我是C新手,所以我对此没有任何线索。 如果可能的话,请build议一些很好的教程链接。
我正在尝试使用QUADPACK例程来执行数值积分。 例程期望函数作为REAL,EXTERNAL传递,所以我没有使用指针或其他任何东西的自由。 是否有可能将函数f(x,a,b,…)作为f(x)的函数来用于仅期望函数x的函数? 就像使用@(x)f(x,a,b,…)在MATLAB完成的一样。
我想使用MPI_GATHER发送2d数据块。例如,我在每个节点上都有2×3数组,如果我有4个节点,我想在根上使用8×3数组。 对于一维数组MPI_GATHER根据MPIsorting数据sorting,但对于二维数据它创build混乱! 整理大块的干净方法是什么? 我期待这个代码的输出: program testmpi use mpi implicit none integer :: send (2,3) integer :: rec (4,3) integer :: ierror,my_rank,i,j call MPI_Init(ierror) MPI_DATA_TYPE type_col ! find out process rank call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierror) if (my_rank==0) then send=1 do i=1,2 print*,(send(i,j),j=1,3) enddo endif if (my_rank==1) then send=5 ! do 1,2 ! print*,(send(i,j),j=1,3) ! enddo endif […]
不知道标题是否正确。 build议欢迎。 这是我想要做的。 检查条件,然后决定在循环中使用哪个函数。 例如: if (a < 0) then loop_func = func1 else loop_func = func2 endif 我可以在编写循环时使用loop_func作为指针。 这两个函数都采用完全相同的input,并且是基于a的值来解决问题的不同方法。 这将允许我只有一个代码块,而不是两个几乎相同的块。 这也可以应用于子程序。 任何想法如何实施? 谢谢。
我最近在向我的FORTRAN程序添加函数时了解了interface block 。 一切工作很好,整齐,但现在我想添加第二个function到interface block 。 这是我的接口块: interface function correctNeighLabel (A,i,j,k) integer :: correctNeighLabel integer, intent(in) :: i,j,k integer,dimension(:,:,:),intent(inout) :: A end function function correctNeighArray (B,d,e,f) character :: correctNeighArray integer, intent(in) :: d,e,f character, dimension(:,:,:),intent(inout) :: B end function end interface 在我看来,这可能不是最好的select。 我已经研究过子程序,但我不是很确信这是正确的解决scheme。 我所做的是相对简单的,我需要将parameter passing给子例程,但是我所看到的所有子例程都是复杂的(即对于函数来说太复杂),并且b)不采取参数performance得像操纵variables而不传递给它们。 我没有真正地查看模块,但从我所看到的是不正确的使用。 任何build议什么时候使用,以及如何去做最好的将非常感激。