【问题标题】:ISO_C_BINDING: Impact on performance/optimizationISO_C_BINDING:对性能/优化的影响
【发布时间】:2013-09-18 07:59:15
【问题描述】:

在使用派生数据类型的 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 时是否还有其他陷阱?对代码施加了哪些限制以及禁用了哪些优化?

【问题讨论】:

    标签: c optimization fortran fortran-iso-c-binding


    【解决方案1】:

    我不会那么担心。 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 在启用所有优化时选择的完全一样。

    iccifortsunccsunf90 也使用相同的对齐方式。

    • 模块iso_c_binding 本身应该对优化没有影响,因为它只是参数、类型定义和过程的集合。它可能会迫使您使用比平时更多的指针。

    【讨论】:

    • 感谢您的解释。所以编译器似乎没有优化结构中元素的顺序。我有点惊讶,因为这样做似乎很简单!我会先咨询给我建议的人——也许我做错了什么……
    • 为了获得最大效率,最好插入填充。它占用更多空间,但访问组件更快,矢量化更容易。
    • 我的意思是对元素进行重新排序...就像 a,c,b 而不是 a,b,c。然后,结构的大小减少到 12,而不是 Fortran 和 C 的 16 个字节。还有一些填充来实现对齐。
    • 在 C 中,编译器不能这样做。在 Fortran 中这是可能的,但对这种情况不是很有好处。
    • 我不太明白 - 为什么它没有好处?如果我(手动)重新排序结构,我会节省一些内存,并且各个组件仍然会对齐!
    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 2021-03-09
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    相关资源
    最近更新 更多