2010-08-08 16 views
5

Kiedy zacząłem programowania w OpenCL użyłem następujące podejście do dostarczania danych do moich jądrachPamięć w OpenCL

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL); 
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL); 

To oczywiście wymaga mnie do podzielenia moje dane w kawałki, zapewniając, że każda porcja będzie pasować do pamięć urządzenia. Po wykonaniu obliczeń odczytałem dane za pomocą clEnqueueReadBuffer(). Jednak w pewnym momencie zdałem sobie sprawę, mogłem po prostu użyć następujący wiersz:

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL); 

Dokonując tego, partycjonowanie danych stało się nieaktualne. Ku mojemu zaskoczeniu doświadczyłem ogromnego wzrostu wydajności. To jest coś, czego nie rozumiem. Z tego, co otrzymałem, przy korzystaniu z wskaźnika hosta, pamięć urządzenia działa jako pamięć podręczna, ale wszystkie dane muszą zostać skopiowane do niego w celu przetworzenia, a następnie skopiowane z powrotem do pamięci głównej po zakończeniu. Jak to się dzieje, że użycie jawnej kopii (clEnqueRead/WriteBuffer) jest wolniejsze o rząd wielkości, kiedy w mojej głowie powinno być w zasadzie takie samo? Czy czegoś brakuje?

Dzięki.

Odpowiedz

2

Tak, brakuje ci CL_TRUE w wywołaniu clEnqueueWriteBuffer. To powoduje blokadę operacji zapisu, która zatrzymuje procesor podczas wykonywania kopii. Za pomocą wskaźnika hosta implementacja OpenCL może "zoptymalizować" kopię, czyniąc ją asynchroniczną, dzięki czemu ogólna wydajność jest lepsza.

Należy pamiętać, że zależy to od implementacji CL i nie ma gwarancji, że będzie szybsza/równa/wolniejsza.

+0

Jestem świadomy flagi blokowania na clEnqueueRead/WriteBuffer. Jednak kiedy zrobiłem środki, użyłem clFinish (przynajmniej jestem tego całkiem pewien), który powinien mieć taki sam efekt jak flaga blokująca, czy nie? Oznacza to oczywiście, że przetwarzana jest ta sama ilość danych. Hm, może implementacja CL jest wystarczająco inteligentna, aby pominąć część obiektu, do którego nie ma dostępu (około 70%) ... Dzięki! – VHristov

1

W niektórych przypadkach procesor i GPU mogą współdzielić tę samą fizyczną pamięć DRAM. Na przykład, jeśli blok pamięci spełnia zasady wyrównania procesora i GPU, Intel interpretuje CL_MEM_USE_HOST_PTR jako uprawnienie do współużytkowania fizycznej pamięci DRAM między procesorem i GPU, więc nie ma faktycznego kopiowania danych. Oczywiście, to bardzo szybko!

Oto link, który wyjaśnia:

https://software.intel.com/en-us/articles/getting-the-most-from-opencl-12-how-to-increase-performance-by-minimizing-buffer-copies-on-intel-processor-graphics

PS Wiem, że moja odpowiedź jest zbyt stary dla PO, ale inni czytelnicy mogą być zainteresowani.