ISO_C_BINDING:对性能/优化的影响

Ale*_*ogt 4 c optimization fortran fortran-iso-c-binding

在具有派生数据类型的MPI的上下文中,我被告知在使用bind(C)构造时要小心,因为它禁止编译器的某些优化.考虑这个(相当不可能的例子):

type, bind(C) :: myType
  integer(2) :: a
  complex    :: z
  integer(2) :: b
end type myType
Run Code Online (Sandbox Code Playgroud)

如果没有该bind(C)语句,编译器可能会重新排序结构并将两个整数分组以便更好地对齐.特别是对于大型结构,当尝试使用自动矢量化时,这将是有益的.

有了bind(C),这种重新组合是不可能的(保持兼容C,编译器可能不会优化那么多).如果所有元素都与单词对齐,或者失去对齐,这将导致大量内存消耗(三个单词而不是两个单词).(至少,我被告知了.)

直到最近,我从未混合使用C和Fortran,并且我从未使用派生类型进行MPI通信.在不久的将来,我将研究混合语言编程,这些问题似乎很重要.

所以我的问题是双重的:

  • bind(C):这种错位会在"真实世界"应用程序中发挥作用吗?有没有人遇到过性能/优化问题?
  • iso_c_binding:(另外)使用模块时是否还有其他陷阱iso_c_binding?对代码施加哪些限制以及禁用哪些优化?

Vla*_*r F 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;
}
Run Code Online (Sandbox Code Playgroud)

我的编译器(gcc在x86_64上)将组件分配到4字节的倍数的地址,即使没有任何优化.更重要的是,对齐gfortran与启用所有优化时选择的完全相同.

同样allignment也使用icc,ifort,sunccsunf90.

  • 模块iso_c_binding本身应该对优化没有影响,因为它只是参数,typedef和过程的集合.它可能会强制您使用比通常更多的指针.