Языки программирования SIMD
-
07-07-2019 - |
Вопрос
В последние пару лет я много занимался программированием на SIMD, и большую часть времени я полагался на встроенные функции компилятора (например, для программирования на SSE) или на ассемблер программирования, чтобы добраться до действительно отличных вещей.Однако до сих пор мне с трудом удавалось найти какой-либо язык программирования со встроенной поддержкой SIMD.
Очевидно, что существуют языки шейдеров, такие как HLSL, Cg и GLSL, которые имеют встроенную поддержку для такого рода вещей, однако я ищу что-то, что способно, по крайней мере, компилироваться в SSE без автовекторизации, но со встроенной поддержкой векторных операций.Существует ли такой язык?
Это пример (часть) Cg-шейдера, который выполняет spotlight, и с точки зрения синтаксиса это, вероятно, самое близкое к тому, что я ищу.
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
- Векторные операции (точка, пересечение, нормализация, насыщение, отражение и так далее)
- Поддержка пользовательских типов данных (структур)
- Динамическое ветвление было бы неплохо (для циклов, операторов if)
Решение 3
Так недавно Intel выпустила ISPC ( ИСПК ) это именно то, что я искал, задавая этот вопрос.Это язык, который может связываться с обычным кодом C, имеет неявную модель выполнения и поддерживает все функции, упомянутые в начальном сообщении (операторы swizzle, ветвление, структуры данных, векторные операции, подобные шейдерам) и компилируется для векторных инструкций SSE2, SSE4, AVX, AVX2 и Xeon Phi.
Другие советы
Вероятно, ваш лучший выбор - это OpenCL.Я знаю, что в основном это рекламировалось как способ запуска кода на графических процессорах, но ядра OpenCL также могут быть скомпилированы и запущены на процессорах.OpenCL - это в основном C с несколькими ограничениями:
- Нет указателей на функции
- Никакой рекурсии
и куча дополнений.В частности, векторные типы:
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 не может вызывать произвольные библиотеки и т.д.Но если ваши вычислительные ядра достаточно независимы, то вы в основном получаете vector enhanced C, где вам не нужно использовать встроенные компоненты.
Здесь это краткий справочник / cheatsheet со всеми расширениями.
На самом деле это не сам язык, но есть библиотека для Mono (Моно.Simd), который предоставит вам векторы и оптимизирует операции над ними в SSE, когда это возможно:
Это библиотека для C ++, а не встроенная в язык, но Eigen становится довольно незаметным после объявления ваших переменных.
В настоящее время лучшим решением является сделать это самому, создав серверную часть для интерфейса Cg с открытым исходным кодом, выпущенного Nvidia, но я хотел бы сэкономить усилия, поэтому мне любопытно, делалось ли это раньше.Предпочтительно, чтобы я начал использовать его прямо сейчас.
Язык программирования D также предоставляет доступ к SIMD аналогичным образом, чем Mono.SIMD.
Это был бы Fortran, который вы ищете.Если памяти хватит, то даже компиляторы с открытым исходным кодом (g95, gfortran) воспользуются преимуществами SSE, если он реализован на вашем оборудовании.