2010-01-10 13 views
7

Piszę własną bibliotekę graficzną (tak, jej zadanie domowe :) i używam cuda, aby szybko wykonać rendering i obliczenia.Rysowanie trójkątów z CUDA

Mam problem z rysowaniem wypełnionych trójkątów. Napisałem to w taki sposób, że jeden proces narysuje jeden trójkąt. Działa bardzo dobrze, gdy na scenie jest dużo małych trójkątów, ale całkowicie zrywa wydajność, gdy trójkąty są duże.

Mój pomysł polega na wykonaniu dwóch karnetów. Najpierw obliczyć tylko kartę z informacjami o liniach skanowania (narysuj od tego miejsca). Byłby to trójkąt na obliczenie procesu, jak w obecnym algorytmie. I w drugim przebiegu naprawdę narysuj linie skanowania z więcej niż jednym procesem na trójkąt.

Ale czy będzie wystarczająco szybki? Może jest jakieś lepsze rozwiązanie?

Odpowiedz

3

Możesz sprawdzić ten blog: Rendering renderowania oprogramowania w CUDA. Nie sądzę, że jest to optymalny sposób, ale przynajmniej autor ma kilka użytecznych źródeł.

Po drugie, przeczytaj ten paper: Programowalna, równoległa architektura renderowania.Myślę, że jest to jedna z najnowszych publikacji i jest również oparta na CUDA.

Gdybym miał to zrobić, chciałbym iść z Danych Parallel rasteryzację Pipeline jak w Larrabee (co jest TBR) lub nawet Reyes i dostosowania go do CUDA:

http://www.ddj.com/architect/217200602 http://home.comcast.net/~tom_forsyth/larrabee/Standford%20Forsyth%20Larrabee%202010.zip (patrz druga część prezentacji)

http://graphics.stanford.edu/papers/mprast/

0

Podejrzewam, że masz pewne nieporozumienia na temat CUDA i jak z niego korzystać, zwłaszcza, że ​​odnoszą się do "procesu", gdy w terminologii CUDA nie ma czegoś takiego.

W przypadku większości aplikacji CUDA istnieją dwie ważne rzeczy, aby uzyskać dobrą wydajność: optymalizacja dostępu do pamięci i upewnienie się, że każdy "aktywny" wątek CUDA w osnowie wykonuje tę samą operację w tym samym czasie, co inne aktywne wątki w osnowie. Oba te dźwięki brzmią, jakby były ważne dla twojej aplikacji.

Aby zoptymalizować dostęp do pamięci, należy się upewnić, że odczyty z pamięci globalnej i zapisy do pamięci globalnej są połączone. Możesz przeczytać więcej na ten temat w przewodniku programowania CUDA, ale zasadniczo oznacza to, że sąsiednie wątki w połowie przeskoku muszą czytać lub zapisywać w sąsiednich lokalizacjach pamięci. Każdy wątek powinien jednocześnie czytać lub zapisywać 4, 8 lub 16 bajtów.

Jeśli wzorzec dostępu do pamięci jest losowy, może być konieczne użycie pamięci tekstury. Kiedy chcesz odwołać się do pamięci, która została odczytana przez inne wątki w bloku, powinieneś skorzystać z pamięci współdzielonej.

W twoim przypadku nie jestem pewien, jakie są twoje dane wejściowe, ale powinieneś przynajmniej upewnić się, że twoje zapisy są połączone. Prawdopodobnie będziesz musiał zainwestować trochę trywialne wysiłki, aby twoje lektury działały sprawnie.

Dla drugiej części, poleciłbym, aby każdy wątek CUDA przetwarzał jeden piksel na wyjściowym obrazie. Przy tej strategii powinieneś uważać na pętle w jądrze, które będą działać dłużej lub krócej w zależności od danych dotyczących wątków. Każdy wątek w twoich osnach powinien wykonać tę samą liczbę kroków w tej samej kolejności. Jedynym wyjątkiem jest to, że nie ma rzeczywistej kary za wydajność, ponieważ niektóre wątki w osnowie nie wykonują żadnej operacji, podczas gdy pozostałe wątki wykonują tę samą operację łącznie.

Dlatego zaleca się, aby każdy wątek sprawdzał, czy jego piksel znajduje się w danym trójkącie. Jeśli nie, nie powinien nic robić. Jeśli tak, powinien obliczyć wyjściowy kolor dla tego piksela.

Ponadto, zdecydowanie polecam więcej informacji na temat CUDA, ponieważ wygląda na to, że skaczę w głęboki kraniec bez dobrego zrozumienia niektórych podstawowych zasad.

+1

Przepraszam za mój język, angielski nie jest moim ojczystym. Więc jaka jest właściwa terminologia do przetwarzania na kartach graficznych? Cóż, myślę, że rozumiem CUDA całkiem dobrze, ale tak, mam brak wiedzy w algorytmach równoległych. Moje wejście to zbiór wierzchołków w przestrzeni obcinania i musiałem narysować trójkąty. Myślę, że algorytm, w którym każdy piksel powinien sprawdzać każdy trójkąt, nie byłby optymalny. – qba

+0

Unikanie każdego piksela sprawdzania każdego trójkąta można wykonać poprzez podział trójkątów za pomocą BVH, KD-Tree lub R-Tree. – whatnick

-1

nie chcę być niegrzeczny, ale nie jest to, co karty graficzne przeznaczone są do zrobienia w każdym razie? Wygląda na to, że używanie standardowych interfejsów OpenGL i Direct3D ma więcej sensu.

Dlaczego nie używać interfejsów API do podstawowego renderowania, a nie CUDA, które jest dużo niższe? Następnie, jeśli chcesz wykonać dodatkowe operacje, które nie są obsługiwane, możesz użyć CUDA, aby zastosować je na górze. A może wdrożyć je jako shaderów.

+0

Tak, tak, rzeczywiście. Ale jego celem jest zbudowanie graficznego rastrowania bez tradycyjnych API. Pomyśl o tym jako o projekcie koncepcyjnym lub edukacyjnym. – Stringer

+0

Tak, mój projekt na moje studia. Musieliśmy sami dokonać wszystkich rasteryzacji. Większość ludzi korzysta z procesora, ale zdecydowałem się użyć CUDA. – qba

+0

Hmm, w takim przypadku brzmi to interesująco. Coś w rodzaju podejścia do tyłu, ale interesujące. – BobMcGee