【问题标题】:SIMD programming languagesSIMD 编程语言
【发布时间】:2010-11-27 21:49:41
【问题描述】:

在过去的几年里,我进行了大量的 SIMD 编程,并且大部分时间我一直依赖编译器内部函数(例如用于 SSE 编程的函数)或编程汇编来实现真正漂亮的东西。然而,到目前为止,我几乎找不到任何内置支持 SIMD 的编程语言。

现在显然有一些着色器语言,例如 HLSL、Cg 和 GLSL,它们对这类东西具有原生支持,但是,我正在寻找至少能够在没有自动矢量化但具有内置支持的情况下编译为 SSE 的东西用于向量运算。这种语言存在吗?

这是一个 Cg 着色器的(部分)示例,它进行聚光灯,就语法而言,这可能是最接近我正在寻找的。​​p>

float4 pixelfunction(
    output_vs IN, 
    uniform sampler2D texture : TEX0, 
    uniform sampler2D normals : TEX1, 
    uniform float3 light, 
    uniform float3 eye ) : COLOR
{
    float4 color    = tex2D( texture, IN.uv );
    float4 normal   = tex2D( normals, IN.uv ) * 2 - 1;

    float3 T = normalize(IN.T);
    float3 B = normalize(IN.B);

    float3 N = 
        normal.b * normalize(IN.normal) +
        normal.r * T +
        normal.g * B;

    float3 V = normalize(eye - IN.pos.xyz);
    float3 L = normalize(light - IN.pos);
    float3 H = normalize(L + V);

    float4 diffuse  = color * saturate( dot(N, L) );
    float4 specular = color * pow(saturate(dot(N, H)), 15);
    float falloff   = dot(L, normalize(light));

    return pow(falloff, 5) * (diffuse + specular);
}

在这种语言中真正必须的东西是:

  • 内置 swizzle 运算符
  • 矢量运算(点、交叉、归一化、饱和、反射等)
  • 支持自定义数据类型(结构)
  • 动态分支会很好(for 循环、if 语句)

【问题讨论】:

    标签: programming-languages sse simd ispc


    【解决方案1】:

    您最好的选择可能是 OpenCL。我知道它主要被宣传为在 GPU 上运行代码的一种方式,但 OpenCL 内核也可以在 CPU 上编译和运行。 OpenCL 基本上是 C 语言,但有一些限制:

    1. 没有函数指针
    2. 无递归

    还有一堆补充。特别是矢量类型:

    float4 x = float4(1.0f, 2.0f, 3.0f, 4.0f);
    float4 y = float4(10.0f, 10.0f, 10.0f, 10.0f);
    
    float4 z = y + x.s3210 // add the vector y with a swizzle of x that reverses the element order
    

    需要注意的是,代码必须完全可操作,OpenCL 不能调用任意库等。但是如果您的计算内核相当独立,那么您基本上会得到一个不需要的向量增强 C使用内在函数。

    Here 是包含所有扩展的快速参考/备忘单。

    【讨论】:

    • 我还能将 OpenCL 库链接到 C 应用程序并为其提供一组向量吗?
    • 正在考虑,它不需要能够链接,我只需要能够传递一些数据:-)
    • 基本上,你编译一个 OpenCL 计算内核,它有一个 C 函数作为入口点,然后运行告诉 OpenCL 使用你指定的参数运行内核,这些参数可以是向量、数据集甚至纹理。
    • 这似乎是我手头问题的最佳解决方案,谢谢。
    • AFAIU OpenCL 需要主机上的驱动程序——使用 OpenCL 的应用程序(例如游戏)如何在 3 个主要桌面平台上发布?
    【解决方案2】:

    这实际上不是语言本身,但有一个 Mono (Mono.Simd) 库,它将向您公开向量并尽可能优化对它们的操作到 SSE:

    【讨论】:

    • 这个解决方案看起来不错;看起来比 C++ 内在函数好得多。但是,该解决方案大致等效,而不是我正在寻找的。 (我一直在寻找使用内置 SIMD 而不是螺栓固定设计的实际语言)。但是,在执行基于 .Net 的解决方案时,绝对要记住这一点。
    【解决方案3】:

    最近英特尔发布了ISPC,这正是我问这个问题时所寻找的。它是一种可以与普通 C 代码链接的语言,具有隐式执行模型,并支持开始文章中提到的所有特性(swizzle 运算符、分支、数据结构、向量操作、类似着色器),并为 SSE2、SSE4、 AVX、AVX2 和 Xeon Phi 矢量指令。

    【讨论】:

    【解决方案4】:

    它是 C++ 的库,而不是内置于语言中,但是一旦声明了变量,Eigen 就完全不可见了。

    【讨论】:

      【解决方案5】:

      目前最好的解决方案是自己做,为 Nvidia 发布的开源 Cg 前端创建一个后端,但我想节省自己的努力,所以我很好奇以前是否做过。我最好马上开始使用它。

      【讨论】:

      • Cg 不是开源的,它是 Nvidia 专有的。创建一个为 CPU 生成 SIMD 代码的后端将是一项巨大的工作。正如 Louis 回答的那样,您应该认真检查 OpenCL。您可以使用基于 C 的语言(非常类似于 Cg 和 GLSL)编写处理内核,并在 GPU 或 CPU(它将为您生成 SIMD 代码)上运行它。 OpenCL 是跨平台的,受到许多供应商(Nvidia、ATI、Apple 等)的支持,您可以立即获得 SDK。
      • Cg 前端源代码可在developer.nvidia.com/object/cg_compiler_code.html 获得 该代码专门用于为编译器创建后端。不过,我更喜欢 OpenCL 等现有解决方案。
      【解决方案6】:

      D 编程语言还以与 Mono.SIMD 类似的方式提供对 SIMD 的访问。

      【讨论】:

        【解决方案7】:

        这将是您正在寻找的 Fortran。如果内存服务于开源编译器(g95、gfortran),如果 SSE 在您的硬件上实现,它也会利用它。

        【讨论】:

        • 那些 Fortran 实现仍然使用自动向量化,就像大多数 C++ 编译器支持它一样。我遇到的问题是很难预测哪些代码将被矢量化,哪些代码不会。现在我不知道这在 Fortran 编译器中的状态,因为我的背景是 C++,所以我认为我更喜欢高级的类似着色器的方法,它可以让我更好地控制最终输出。
        猜你喜欢
        • 2011-04-11
        • 2017-09-07
        • 2014-10-07
        • 2011-08-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多