我们得到了一个12核的MacPro来进行蒙特卡罗计算.它的Intel Xeon处理器启用了超线程(HT),因此实际上应该有24个进程并行运行以充分利用它们.但是,我们的计算效率比12x100%高出24x50%更高效,因此我们尝试Processor在系统首选项中通过窗格关闭超线程以获得更高的性能.人们也可以关闭HT
hwprefs -v cpu_ht=false
Run Code Online (Sandbox Code Playgroud)
然后我们进行了一些测试,这是我们得到的:
似乎超线程只是降低了我们计算的性能,并且没有办法避免它.我们用于计算的程序是用Fortran编写的,并使用gfortran.有没有办法让这个硬件更高效?
更新:我们的蒙特卡罗计算(MCC)通常是分步进行的,以避免数据丢失和由于其他原因(并不总是可以避免这些步骤).在我们的例子中,每一步都包含许多具有可变持续时间的模拟.由于每个步骤在多个并行任务之间分割,因此它们也具有可变持续时间.基本上,所有更快的任务都必须等到最慢完成.这一事实迫使我们采取更大的步骤,由于平均而导致时间偏差减少,因此处理器不会浪费时间等待.这是我们拥有12*2.66 GHz而不是24*1.33 GHz的动机.如果可以关闭HT,那么通过从24个任务w/HT切换到12个没有HT的任务,我们可以获得大约+ 10%的性能.但是,测试表明我们松了20%.
对于测试,我使用了相当大的步骤,但通常步骤较短,因此效率变得更高.
还有一个原因 - 我们的一些计算需要3-5 GB的内存,因此您可能会看到我们有12个快速任务的经济性.我们正在努力实现共享内存,但它将成为一个冗长的术语项目.因此,我们需要了解如何尽可能快地制作现有的硬件/软件.
根据这个,gfortran可以进行整数逻辑转换,但是我收到了这个错误:
if (.not.bDropped.and.(zz_unif01() .lt. (1 - (Test_Dru
1
Error: Operand of .not. operator at (1) is INTEGER(4)
Run Code Online (Sandbox Code Playgroud)
我知道这将是更好的代码从改变.not.bDropped到(bDropped.eq.0),但因为它生成的代码不会是简单的.
我试过各种各样的-std=xxx旗帜,但没有区别.
我正在寻找一种将逻辑类型变量转换为真实类型的防弹方式,这种方式可以在ifort和gfortran中使用.以下适用于ifort,但不适用于gfortran:
logical :: a
real :: b
a = .true.
b = dble(a)
Run Code Online (Sandbox Code Playgroud)
gfortran中抛出的错误是
b = dble(a)
1
Error: 'a' argument of 'dble' intrinsic at (1) must be a numeric type
Run Code Online (Sandbox Code Playgroud)
显然,.true.应映射到1.d0和.false.到0.d0.这样做的最佳方法是什么?
我是Fortran的新手.我正在研究一个研究项目,我正在使用一个开源项目,该项目有多个文件分布在多个文件夹中.我发现每个程序的依赖性,但无法弄清楚如何编译它们.
我的源代码分布在三个文件夹中.a)模块b)接口c)子程序
我想在子程序文件夹中运行一个名为'Main.f90'的程序,该程序依赖于来自模块和接口文件夹的源代码.
我正在使用eclipse进行文件夹结构和makefile进行编译.
对此有任何帮助表示赞赏.
更新: 我按照@MBR和@Stefan发布的答案,由于某种原因VPATH无法在源代码中找到程序,所以我明确地给了我的Makefile中的源文件夹路径.下面是我的make文件脚本.
.PHONY: Mopac_exe clean
# Change this line if you are using a different Fortran compiler
FORTRAN_COMPILER = gfortran
SRC = src
#make main program
Mopac_exe: subroutines mopac.o
$(FORTRAN_COMPILER) mopac.o *.o -O2 -g -o bin/Mopac_exe -I Modules/
#compile all the subroutines
subroutines: interfaces
$(FORTRAN_COMPILER) -c $(SRC)/subroutines/*.F90 -J Modules/Subroutines/ -I Modules/
#compiles all the interfaces
interfaces: modules
$(FORTRAN_COMPILER) -c $(SRC)/interfaces/*.f90 -J Modules/
# build all the modules and generate .mod file in Modules …Run Code Online (Sandbox Code Playgroud) [无耻地从CMake帮助列表中交叉发布]
我正试图尽可能静态地创建二进制文件.我得到的fortran代码有X11和quadmath作为依赖项,我遇到了很多问题(可能每个问题都应该是一个不同的问题?):
我的变量目前是
set(CMAKE_LIBRARY_PATH /usr/X11/lib /usr/X11/include/X11 ${CMAKE_LIBRARY_PATH})
find_package(X11 REQUIRED)
find_library(X11 NAMES X11.a PATHS /usr/X11/include/X11/ /usr/X11/lib)
find_library(X11_Xaw_LIB NAMES Xaw Xaw /usr/X11/include/X11/ /usr/X11/lib ${X11_LIB_SEARCH_PATH})
find_library(Xaw Xaw7 PATHS ${X11_LIB_SEARCH_PATH})
set(CMAKE_LIBRARY_PATH /usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/x32 /usr/lib/gcc/x86_64-linux-gnu/4.7/32 ${CMAKE_LIBRARY_PATH})
find_library(quadmath NAMES quadmath.a)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(LINK_SEARCH_START_STATIC TRUE)
set(LINK_SEARCH_END_STATIC TRUE)
set(SHARED_LIBS OFF)
set(STATIC_LIBS ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
Run Code Online (Sandbox Code Playgroud)使用这些,CMake尝试静态地构建每个程序(如预期的那样) - 然而,它失败了因为我没有Xaw.a- 我无法确定这是否真的应该存在.我已经安装了libxaw7-dev我期望修复它的最新版本.一种选择是自己编译X11库,但我真的不想这样做......
如果我只set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")注释掉,那么CMake会编译所有内容,但是每个程序都使用共享库,即使我.a在find_library()调用中指定了X11库的位置.我期待CMake在可能的地方使用.a文件然后只使用共享库 - 有没有办法强制这种行为?
有没有人知道这里描述的错误修复:http://gcc.gnu.org/bugzilla/show_bug.cgi?id = …
有没有办法控制GNU Fortran 4.8发出的符号?
较旧的版本(例如3.4)分别使用了源和大写的情况-fcase-lower,-fcase-preserve并且-fcase-upper强制小写,但这些似乎已被丢弃.是否有一些新的控制方式?
编辑
我正在尝试将一个大型的,混合的C/Fortran代码库从英特尔编译器移植到GNU编译器.
我知道我们可以BIND(C, name='...')用来给出一个特定于案例的符号名称.但是,这还有其他影响.考虑这个C函数:
void print(char *str, size_t len) {
for(int ii = 0; ii < len; ii++) {
putchar(str[ii]);
}
putchar('\n');
}
Run Code Online (Sandbox Code Playgroud)
我们可以从这样的Fortran程序中调用它:
program test
implicit none
interface
subroutine printstr(str)
character :: str(*)
end subroutine
end interface
call printstr("Hello, world.");
end
Run Code Online (Sandbox Code Playgroud)
如果C函数名称不是全部小写(PrintStr比如说),那么我们可能会尝试修复Fortran程序,如下所示:
program test
implicit none
interface
subroutine printstr(str) bind(C, name='PrintStr')
use iso_c_binding
character :: str(*)
end subroutine
end interface
call printstr("Hello, world.");
end
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为 …
GNU Fortran编译器的GNU扩展提供了GETCWD()很好的子例程,获取当前工作目录.然而,我的代码必须是移植到ifort和nagfor编译器,以及和我使用F2003功能.
那么,GETCWD()F2003及更高版本有替代品吗?
我在这里有标准,但它相当大,我现在已经经历了一段时间,并没有找到任何有用的东西......
我在一个程序中有一节写入直接访问二进制文件,如下所示:
open (53, file=filename, form='unformatted', status='unknown',
& access='direct',action='write',recl=320*385*8)
write (53,rec=1) ulat
write (53,rec=2) ulng
close(53)
Run Code Online (Sandbox Code Playgroud)
该程序使用ifort编译.但是,如果我从使用gfortran编译的其他程序中读取数据文件,则无法正确重建数据.如果读取数据的程序也在ifort中编译,那么我可以正确地重建数据.这是读取数据文件的代码:
OPEN(53, FILE=fname, form="unformatted", status="unknown", access="direct", action="read", recl=320*385*8)
READ(53,REC=2) DAT
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样?我可以用两个编译器正确读取第一条记录,这是我混合编译器时无法正确重建的第二条记录.
有没有办法在gfortran强制下溢到下溢?
我不敢相信这是第一次有人问这个,但我找不到任何东西.Mea culpa如果这是重复的话.
场景(见下面的代码):考虑一些 Fortran 模块my_module,它包含两个派生类型的定义:test(parent) 和sub_test(extends test, subclass)。除了两个构件a和b父类的,sub_test定义了一个新成员c。最终,该模块my_module将用于某些程序中my_program。
module my_module
implicit none
private
public :: test, sub_test
type :: test
integer :: a = 1
integer :: b = 2
end type test
type, extends(test) :: sub_test
integer :: c = 3
contains
procedure, public :: increment
end type sub_test
contains
subroutine increment (this)
class(sub_test) :: this
this % a = this …Run Code Online (Sandbox Code Playgroud) gfortran ×10
fortran ×8
binaryfiles ×1
cmake ×1
debugging ×1
fortran2003 ×1
fortran2008 ×1
gcc ×1
gdb ×1
intel ×1
linux ×1
macos ×1
module ×1
multifile ×1
subroutine ×1
underflow ×1