SIMD编程语言

10
在过去的几年中,我一直在进行大量的SIMD编程,大多数情况下我依赖于编译器内置函数(例如用于SSE编程的函数)或者编写汇编代码来获得真正妙不可言的东西。然而,到目前为止,我几乎找不到任何具有内置SIMD支持的编程语言。
显然,着色器语言(如HLSL、Cg和GLSL)具有本地支持此类功能的能力,但是,我正在寻找的是至少可以编译为SSE而不是使用自动矢量化,但具有内置矢量操作支持的语言。是否存在这样的编程语言?
以下是一个 Cg 着色器的示例,它执行聚光灯操作,在语法方面,这可能是最接近我所需要的内容。
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 语句)
8个回答

8

最近,英特尔发布了ISPC,这正是我在提问时所寻找的东西。它是一种能够与普通的 C 代码链接的语言,具有隐式执行模型和对起始帖子中提到的所有功能(swizzle 操作符、分支、数据结构、向量操作、像着色器一样)的支持,并编译为 SSE2、SSE4、AVX、AVX2 和 Xeon Phi 向量指令。


固定链接:https://ispc.github.io/ 或 https://github.com/ispc/ispc - Jack Valmadre

7

你最好的选择可能是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,您不需要使用内部函数。 这里 是一个包含所有扩展的快速参考/备忘单。

我是否仍然可以将OpenCL库链接到C应用程序并将一组向量传递给它? - Jasper Bekkers
考虑到这一点,它不需要能够链接,我只需要能够传递一些数据即可 :-) - Jasper Bekkers
1
基本上,您编译一个具有C函数作为入口点的OpenCL计算内核,然后告诉OpenCL使用您指定的参数运行内核,这些参数可以是向量、数据集甚至纹理。 - Louis Gerbarg
这似乎是我手头问题的最佳解决方案,谢谢。 - Jasper Bekkers
据我所知,OpenCL需要在主机上安装驱动程序--那么一个使用OpenCL的应用程序(比如游戏)将如何在三个主要桌面平台上发布? - user519179

6

实际上并不是语言本身的问题,而是Mono(Mono.Simd)有一个库,它可以向您公开向量,并在可能时将对它们的操作优化为SSE:


这个解决方案看起来不错,比C++内置函数要好得多。然而,这个解决方案大致等效,并不是我想要的。 (我正在寻找实际上具有SIMD内置功能的编程语言,而不是后期添加的)。但是,在进行基于.NET的解决方案时,这绝对是值得记住的东西。 - Jasper Bekkers

2

这是一个C++库,而不是内置于语言中的,但是一旦声明了变量,Eigen就会变得非常隐形。


0

你需要的是Fortran语言。如果我没记错,即使是开源编译器(g95、gfortran)也会利用SSE技术,如果你的硬件支持的话。


3
这些Fortran实现仍然以与大多数C++编译器相同的方式支持自动向量化。 我对此的问题是很难预测哪些代码将被向量化,哪些代码不会被向量化。现在我不知道Fortran编译器中的情况,因为我的背景是在C++方面,所以我认为我更喜欢一种高级着色器样式的方法,它可以让我对最终输出具有更多的控制权。 - Jasper Bekkers

0

目前最好的解决方案是通过为Nvidia发布的开源Cg前端创建后端来自己完成,但我想节省自己的精力,所以我很好奇是否已经有人做过了。最好的情况是我可以立即开始使用它。


Cg不是开源的,它是Nvidia专有的。为CPU创建生成SIMD代码的后端将需要大量工作。正如Louis所回答的,你应该认真考虑OpenCL。你可以用基于C的语言编写处理内核(与Cg和GLSL非常相似),并在GPU或CPU上运行它(在CPU上,它将为你生成SIMD代码)。OpenCL是跨平台的,得到许多厂商的支持(如Nvidia、ATI、苹果等),你可以立即获得一个SDK。 - gavinb
Cg前端源代码可在http://developer.nvidia.com/object/cg_compiler_code.html上获得。该代码专门用于为编译器创建后端。然而,我更喜欢现有的解决方案,如OpenCL。 - Jasper Bekkers

0

D编程语言也提供了类似于Mono.SIMD的方式来访问SIMD。


0

我知道这个问题有点老了,但我发现自己陷入了类似的困境,决定自己动手解决。

我还没有取得太大进展,但如果你对我正在探索的方向感兴趣,那么看一看可能是值得的。:)

https://github.com/HappMacDonald/MasterBlaster

MasterBlaster是一种函数式编程语言,但它将被编译成一个字节码,最终成为自己的简化栈式语言Crude。Crude然后直接编译成汇编。

我的策略是先采用SIMD:未经过优化的可执行文件几乎完全使用SIMD,然后潜在的优化之一是将没有从SIMD中受益的代码简化为仅使用通用寄存器。

Crude已经达到了图灵完备阶段,但目前只存在几十个GAS宏。我正在努力实现一个自包含的编译器,并构建迭代器/生成器功能,这些功能是在进行SIMD加速时的主角。

目前还没有向量矩阵等支持,但这在路线图上,当我撰写该语法时,我可能会考虑您的描述。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接