Przede wszystkim: daj sobie spokój z SFML. Będzie cie tylko ograniczać. Poza tym - SFML to wysokopoziomowa nakładka na OpenGL , a CUDA to jeszcze kolejne API. Bardzo sobie komplikujesz mieszając dwa różne API. Szczerze, to nie wiem jak tu wyglądają możliwości, ale na pewno bardzo utrudnia sprawe i całkiem możliwe, że to nakłada spadek wydajności i/lub konieczność dodatkowej synchronizacji. Plus myślę, że mogę być całkiem pewien, że z abstrakcją jaką ci robi SFML nawet nie ma szans, chyba że zamierzasz użyć SFML tylko do kreacji contextu (chociaż nie wiem czy w ogóle potrafi tworzyć core profile context).
tl;dr: odradzam mieszać graphics api przyanjmniej na początku nauki i polecam pozbyć się SFML
jeżeli na GPU policzę pozycje, kolor itd każdego particla (dajmy na to że będzie ich milion) i potem będę to wszystko kopiował do cpu tylko po to by za chwile użyć milion razy draw mija się z celem. i teraz mam takie pytanie. Jak to zrobić lepiej?
Nie ma potrzeby kopiowania do cpumem skoro GPU zarówno liczy ruch jak i rysuje. Wszystko powinno się dziać w gpumem. No i nie ma żadnego milion razy draw (podejrzewam, że tutaj myślisz o SFML?). Dlatego mówię, żebyś wyrzucił SFML, tylko korzystał z OpenGL 4.5 core profile które teraz oferuje naprawdę dużo - nawet nie ma potrzeby wspomagania się CUDA, bo masz compute shader (chociaż zgadzam się, że CUDA jest przyjemniejsza).
Może wy macie jakieś doświadczenia z rysowaniem tak wielu obiektów na raz?
Wszytkie particle rysujesz jako jeden mesh z primitivem GL_POINTS. I to jest jeden drawcall. Jak to się z reguły robi: masz buffer (tj. jakaś alokacja gpumem) z pozycjami miliona particli. Za pomocą compute shader (albo CUDA jeśli już musisz i ogarniesz jak to się robi) modyfikujesz pozycje (możesz mieć jeszcze jeden buffer np. z prędkością). Tutaj (między compute a draw) potrzebujesz sync call z odpowiednią flagą - w OpenGL glMemoryBarrier. Rysujesz to za pomocą glDrawArrays, ale geometry shader z każdego takiego punkcika robi 4 jako triangle_strip - tzn prostokąt. Teraz ten kwadrat możesz już sobie teksturować, kolorować czy cokolwiek chcesz. I tak w kółko. To w dużym skrócie - musisz znać wiele szczegółow, ale generalnie to nie jest nic trudnego, poradzisz sobie. https://www.3dgep.com/opengl-interoperability-with-cuda/
miałem inny pomysł by jedna funkcja GPU liczyła pozycje particli a druga wywołana tuż po obliczeniach rasteryzowała je na teksturze która potem by była w całości wyświetlona
Tak, dokładnie tak powinna wyglądać pętla.
Jako reference: https://github.com/Crisspl/GPU-particle-system kiedyś zrobiłem coś bardzo podobnego, może ci się przydać jako odniesienie jakieś. Kod bezpośrednio do particli jest w particles/main.cpp. PS: jak teraz patrze to flaga w glMemoryBarrier jest skopana, nie sugeruj się tym :P