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.
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