2009-09-13 19 views
12

W ciągu ostatnich kilku lat zajmowałem się programowaniem SIMD i przez większość czasu polegałem na wewnętrznych funkcjach kompilatora (takich jak te do programowania SSE) lub na programowaniu aby dostać się do naprawdę fajnych rzeczy. Jednak do tej pory nie byłem w stanie znaleźć żadnego języka programowania z wbudowaną obsługą SIMD.Języki programowania SIMD

Teraz oczywiście istnieją języki modułu cieniującego, takie jak HLSL, Cg i GLSL, które mają natywne wsparcie dla tego rodzaju rzeczy, ale szukam czegoś, co jest w stanie skompilować przynajmniej do SSE bez automatycznego uwewnętrznienia, ale z wbudowanym obsługa operacji wektorowych. Czy taki język istnieje?

To jest przykład (części) cieniowania Cg, który działa w świetle punktowym i pod względem składni jest prawdopodobnie najbliższy temu, czego szukam.

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); 
} 

Stuff to byłby prawdziwy musi w tym języku brzmi:

  • Wbudowany operatorów swizzle
  • operacje wektorowe (kropka, krzyż, normalizują, nasycić, odzwierciedlają et cetera)
  • Obsługa niestandardowych typów danych (struktur)
  • Dynamiczne rozgałęzienie byłoby miłe (dla pętli, jeśli instrukcje)

Odpowiedz

6

Niedawno Intel wydał ISPC, dokładnie to, czego szukałem, zadając to pytanie. Jest to język, który może łączyć się z normalnym kodem C, ma i niejawny model wykonania oraz obsługą wszystkich funkcji wspomnianych w poście początkowym (operatory swizzle, rozgałęzienia, struktury danych, operacje wektorowe, shadery) i kompiluje dla SSE2, SSE4, Instrukcje wektorowe AVX, AVX2 i Xeon Phi.

0

To będzie Fortran, którego szukasz. Jeśli pamięć obsługuje nawet kompilatory open-source (g95, gfortran), skorzysta z SSE, jeśli jest zaimplementowany na twoim sprzęcie.

+2

Te implementacje Fortranu nadal używają wektoryzacji automatycznej w taki sam sposób, w jaki obsługuje to większość kompilatorów C++. Problem z tym jest taki, że bardzo trudno jest przewidzieć, jaki kod będzie wektoryzowany, a który nie. Teraz nie znam stanu tego w kompilatorach Fortran, ponieważ moje środowisko jest w C++, więc myślę, że wolałbym podejście do shaderów na wysokim poziomie, które daje mi większą kontrolę nad końcowym wyjściem. –

6

To naprawdę nie sam język, ale nie jest biblioteką dla Mono (Mono.Simd), które będą wystawiać wektory do ciebie i optymalizować operacje na nich w SSE w miarę możliwości:

+0

To rozwiązanie wygląda ładnie; wygląda znacznie lepiej niż wewnętrzna C++. Jednak rozwiązanie jest mniej więcej równoważne, a nie to, czego szukam. (Szukałem rzeczywistych języków zaprojektowanych za pomocą wbudowanego SIMD zamiast przykręcanego). Jednak z pewnością warto o tym pamiętać przy korzystaniu z rozwiązania opartego na .Net. –

0

Obecnie najlepszym rozwiązaniem jest, aby zrobić to samo, tworząc back-end dla open-source Cg frontend, że Nvidia wydany, ale chciałbym zaoszczędzić sobie wysiłku, więc jestem ciekawy, czy to zostało zrobione wcześniej. Najlepiej zacznę go używać od razu.

+0

Cg nie jest open source, jest własnością Nvidii. Ogromnym nakładem pracy byłoby stworzenie zaplecza generującego kod SIMD dla procesora. Jak Louis odpowiada, powinieneś poważnie sprawdzić OpenCL. Możesz pisać jądra przetwarzania w języku opartym na C (bardzo podobnym do Cg i GLSL) i uruchamiać go na procesorze graficznym lub procesorze (gdzie wygeneruje kod SIMD dla ciebie). OpenCL jest wieloplatformowy, obsługiwany przez wielu dostawców (Nvidia, ATI, Apple, itp.) I możesz od razu otrzymać pakiet SDK. – gavinb

+0

Kod źródłowy strony głównej jest dostępny pod adresem http://developer.nvidia.com/object/cg_compiler_code.html Kod jest udostępniany specjalnie do tworzenia zaplecza dla kompilatora. Preferuję jednak istniejące rozwiązania, takie jak OpenCL. –

7

Twój najlepszy zakład to prawdopodobnie OpenCL. Wiem, że w większości był to hiper jako sposób uruchamiania kodu na procesorach GPU, ale kernele OpenCL mogą być również kompilowane i uruchamiane na procesorach. OpenCL jest w zasadzie C z kilkoma ograniczeniami:

  1. Brak wskaźników funkcji
  2. Nie rekursji

i kilka dodatków. W poszczególnych typach Vector:

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 

Na dużym zastrzeżeniem jest to, że kod musi być czysto sperable, OpenCL nie może wołać do dowolnych bibliotek itp Ale jeśli twoje jądra obliczeniowe są dość niezależne, to można w zasadzie uzyskać wektor wzmocniony C, w którym nie trzeba używać samoistnie.

Here to szybkie odniesienie/cheatsheet z wszystkimi rozszerzeniami.

+0

Czy nadal mogę połączyć biblioteki OpenCL z aplikacją C i przekazać jej zestaw wektorów? –

+0

Przyszedł czas, aby się nad tym zastanowić, nie musi być możliwe łączenie, wystarczy, że będę mógł przekazać mu kilka danych :-) –

+1

Zasadniczo, kompilujemy jądro obliczeniowe OpenCL, które ma funkcję C jako punkt wejścia , następnie uruchom polecenie OpenCL, aby uruchomić jądro przy użyciu określonych parametrów, które mogą być wektorami, zestawami danych, a nawet teksturami. –

1

Jest to biblioteka dla C++, a nie wbudowana w język, ale Eigen jest dość niewidoczny po zadeklarowaniu zmiennych.

0

Język programowania D zapewnia również dostęp do SIMD w podobny sposób, jak Mono.SIMD.