在具有派生数据类型的MPI的上下文中,我被告知在使用bind(C)
构造时要小心,因为它会禁止编译器的某些优化。考虑这个(相当不可能的例子):
type, bind(C) :: myType
integer(2) :: a
complex :: z
integer(2) :: b
end type myType
如果没有bind(C)
语句,编译器可能会重新排序结构并将两个整数分组以便更好地对齐。特别是对于大型结构,当尝试使用自动矢量化时,这将是有益的。
使用bind(C)
,这种重新组合是不可能的(与C
保持兼容,编译器可能不会那么优化)。如果所有元素都与单词对齐,或者失去对齐,这将导致大量内存消耗(三个单词而不是两个单词)。 (至少,我被告知过。)
直到最近,我从未混合使用C和Fortran,而且我从未使用派生类型进行MPI通信。在不久的将来,我将研究混合语言编程,这些问题似乎很重要。
所以我的问题是双重的:
bind(C)
:这种错位会在“真实世界”的应用程序中发挥作用吗?有没有人在这里遇到性能/优化问题?iso_c_binding
:(另外)使用模块iso_c_binding
时是否还有其他陷阱?对代码施加了哪些限制以及哪些优化被禁用?答案 0 :(得分:5)
我不会那么担心。 C编译器也会在结构中插入填充,特别是当元素不是4个字节的倍数时。更糟糕的是sequence
,但这是不同的。
在C:
中尝试使用此等效的派生类型#include <stdio.h>
#include <stdint.h>
#include <complex.h>
typedef struct{
int16_t a;
float complex b;
int16_t c;
} t;
int main(){
t o;
printf("%x %x %x \n",&o.a,&o.b,&o.c);
return 0;
}
我的编译器(x86_64上的gcc
)将组件分配到4字节倍数的地址,即使没有任何优化也是如此。更重要的是,对齐与gfortran
在启用所有优化时选择的完全相同。
icc
,ifort
,suncc
和sunf90
也使用相同的号码。
iso_c_binding
本身应该对优化没有影响,但是它只是参数,typedef和过程的集合。它可能会强迫您使用比通常更多的指针。