代码之家  ›  专栏  ›  技术社区  ›  fish2000

从cmake运行具有最佳编译器标志和配置的Halide生成器

  •  3
  • fish2000  · 技术社区  · 8 年前

    好的,那么:我已经成功集成了第一个工作 Halide generator 进入 cmake build system 为了我的孩子 image-processing project .

    该生成器基于Halide代码库中的示例代码实现图像大小调整和重采样算法 Halide/apps/resize/resize.cpp 我修改了示例以利用生成器参数,并使用中定义的函数将生成器编译和调用绑定到我的cmake脚本 HalideGenerator.cmake ,就像Halide项目在自己的构建脚本中所做的那样。

    tools scripts ,我对代码生成过程只有最肤浅的了解。

    # If you're compiling and linking multiple Halide pipelines, then the
    # multiple copies of the runtime should combine into a single copy
    # (via weak linkage). If you're compiling and linking for multiple
    # different targets (e.g. avx and non-avx), then the runtimes might be
    # different, and you can't control which copy of the runtime the
    # linker selects.
    
    # You can control this behavior explicitly by compiling your pipelines
    # with the no_runtime target flag. Let's generate and link several
    # different versions of the first pipeline for different x86 variants: [snip]
    

    很难从中分离出 必须 做什么,从什么开始 应该 做什么,或者做什么 也许 随意地做。相比之下,在设置C++或Objective-C项目(甚至更多拜占庭式的例子)时,不必处理这些问题,因为编译器和链接器为您做出了大多数这些决定,最多只需要一两个标志。

    我的问题是:如何将Halide生成器输出库二进制文件集成到现有项目中,以使生成器输出尽可能快(例如,使用GPU、SSE2/3、AVX2等) 没有 进一步限制了可移植性(例如,它不会在稍有不同的机器上神秘地分段)?

    具体来说,我的流程应该是什么样的?我应该首先只针对最低的公分母,然后逐步利用更奇特的处理器功能吗?


    编辑:正如我在下面的注释中提到的,这是我的GenGen二进制输出 stdout 在没有选项的情况下调用时:

    Imgur

    2 回复  |  直到 8 年前
        1
  •  2
  •   Steven Johnson    8 年前

    最近,AOT编译现在支持通过运行时检测为多个CPU功能生成自定义。只需使用带有逗号分隔的目标列表和static_library的GenGen作为输出,例如。

    GenGen-e static_library,h目标=x86-64-linux-sse41-avx,x86-64-linux-sse41,x86-6 4-linux

    这将生成一个.a文件,其中包含:

    • 3个版本的代码,使用AVX+SSE4.1、SSE4.1和plain-old-x86-64的专门功能编译
    • 使用卤化物canusetargetfeatures()运行时调用为实际目标机器选择正确的包装器

    请参阅Func::compile_to_multitarget_static_library()和multittarget_generator.cpp/multitarget_aottest。cpp了解更多信息。

        2
  •  1
  •   Khouri Giordano    8 年前

    • 选择一组目标高级功能(高性能桌面GPU)作为最佳案例,并选择一组适用于每台机器的最低功能(仅限SSE2)。
    • 为这些特性集中的每一个构建一个DLL/dylib/so,其中包含每一个性能要求很高的函数。这些计划可以不同,甚至可以完全不同 Func 定义。您可以将这两个集合放在同一个源代码文件中,并测试 Target 对象在生成时进行选择。
    • 在程序启动时,查看您的最佳案例功能是否存在,如果存在,请加载该库并使用它。如果缺少任何功能,则默认为最兼容的版本。

    您可以自由选择要支持的要素集和库的数量。

    另一种方法是在程序启动(JIT)时编译Halide代码。我建议使用 目标 返回的对象 get_jit_target_from_environment() ,它使用环境变量的内容 HL_JIT_TARGET get_host_target() 这意味着Halide将检查CPU/GPU环境并设置它发现的任何特性。然后可以动态测试 目标 对象并使用GPU或CPU调度。