Czym właściwie jest rodzina kolejek w Vulkanie?

Obecnie uczę się vulkana, w tej chwili rozkładam na części każde polecenie i sprawdzam struktury, aby spróbować zrozumieć, co one oznaczają.

W tej chwili analizuję kolejkę, dla której mam następujący kod:

vector<vk::QueueFamilyProperties> queue_families = device.getQueueFamilyProperties();
for(auto &q_family : queue_families)
{
    cout << "Queue number: "  + to_string(q_family.queueCount) << endl;
    cout << "Queue flags: " + to_string(q_family.queueFlags) << endl;
}

Daje to wyjście:

Queue number: 16
Queue flags: {Graphics | Compute | Transfer | SparseBinding}
Queue number: 1
Queue flags: {Transfer}
Queue number: 8
Queue flags: {Compute}

Więc naiwnie rozumiem to w ten sposób:

Istnieją 3 rodziny kolejek, jedna rodzina kolejek ma 16 kolejek, wszystkie zdolne do grafiki, obliczania, transferu i rzadkiego binding operations (no idea what the last 2 are)

Inny ma 1 kolejkę, zdolną tylko do transferu (cokolwiek to jest)

A ostatnia ma 8 kolejek zdolnych do operacji obliczeniowych.

Czym jest rodzina kolejek? Rozumiem, że tam wysyłamy polecenia wykonawcze, takie jak rysowanie i zamiana buforów, ale jest to dość szerokie Wyjaśnienie, chciałbym znać bardziej szczegółową odpowiedź.

Jakie są 2 dodatkowe flagi? Transfer i SparseBidning?

I wreszcie, dlaczego mamy / potrzebujemy wielu kolejek poleceń?

Author: Makogan, 2019-03-21

2 answers

Aby zrozumieć rodziny kolejek, musisz najpierw zrozumieć kolejki.

Kolejka to coś, do czego wysyłamy bufory poleceń, a bufory poleceń przesłane do kolejki są wykonywane w kolejności [*1] względem siebie. Bufory poleceń przesyłane do różnych kolejek nie są uporządkowane względem siebie, chyba że zostaną wyraźnie zsynchronizowane z VkSemaphore. Pracę do kolejki można przesyłać tylko z jednego wątku na raz, ale różne wątki mogą przesyłać pracę do różnych kolejek jednocześnie.

Każda kolejka może wykonywać tylko określone operacje. Kolejki graficzne mogą uruchamiać potoki graficzne uruchamiane poleceniami vkCmdDraw*. Kolejki obliczeniowe mogą uruchamiać potoki obliczeniowe uruchomione przez vkCmdDispatch*. Kolejki transferu mogą wykonywać operacje transferu (kopiowania) z vkCmdCopy*. Kolejki Sparse binding mogą zmienić powiązanie sparse resources z pamięcią za pomocą vkQueueBindSparse (zauważ, że jest to operacja przekazywana bezpośrednio do kolejki, a nie polecenie w buforze poleceń). Niektóre kolejki mogą wykonywać wiele rodzajów operacji. W specyfikacji każde polecenie, które może zostać przesłane do kolejki, ma tabelę "właściwości polecenia", która zawiera listę typów kolejek, które mogą wykonać polecenie.

Rodzina kolejek opisuje tylko zbiór kolejek o identycznych właściwościach. Tak więc w twoim przykładzie urządzenie obsługuje trzy rodzaje kolejek:

  • Jeden rodzaj może wykonywać operacje graficzne, obliczeniowe, transferowe i nieliczne wiązania, a Ty możesz utworzyć do 16 kolejek tego typu.

  • Inny rodzaj może wykonuj tylko operacje transferu i możesz utworzyć tylko jedną kolejkę tego rodzaju. Zwykle jest to asynchronicznie DMAing danych między hostem a pamięcią urządzenia na oddzielnych GPU, więc transfery mogą być wykonywane jednocześnie z niezależnych operacji graficznych / obliczeniowych.

  • Wreszcie, można utworzyć do 8 kolejek, które są zdolne tylko do operacji obliczeniowych.

Niektóre kolejki mogą odpowiadać tylko oddzielnym kolejkom w harmonogramie po stronie hosta, inne mogą odpowiadać do rzeczywistych niezależnych kolejek w sprzęcie. Na przykład, wiele GPU ma tylko jedną sprzętową kolejkę grafiki, więc nawet jeśli utworzysz dwa VkQueues z rodziny kolejek obsługujących grafikę, bufory poleceń przesłane do tych kolejek będą przebiegać przez harmonogram bufora poleceń sterownika jądra niezależnie, ale będą wykonywane w pewnej kolejności szeregowej na GPU. Ale niektóre GPU mają wiele kolejek sprzętowych tylko do obliczeń, więc dwa VkQueues dla rodziny kolejek tylko do obliczeń mogą działać niezależnie i jednocześnie przez GPU. Vulkan tego nie ujawnia.

Podsumowując, zdecyduj, ile kolejek możesz z pożytkiem wykorzystać, na podstawie ilości współbieżności. W przypadku wielu aplikacji wystarczy jedna "uniwersalna" Kolejka. Bardziej zaawansowane mogą mieć jedną kolejkę graficzną+obliczeniową, oddzielną kolejkę tylko obliczeniową dla asynchronicznej pracy obliczeniowej oraz kolejkę transferu dla asynchronicznego DMA. Następnie Mapuj to, co chcesz na to, co jest dostępne; być może będziesz musiał zrobić własne multipleksowanie, np. na urządzenie, które nie ma rodziny kolejek obliczeniowych, może zamiast tego utworzyć wiele kolejek graficznych + obliczeniowych lub samodzielnie serializować zadania obliczeniowe asynchroniczne na pojedynczej kolejce graficznej + obliczeniowej.

[*1] trochę upraszczając. Są one zaczynają W porządku, ale mogą postępować niezależnie od tego i zakończyć się w porządku. Niezależne postępy w różnych kolejkach nie są jednak gwarantowane. Zostawię to na to pytanie.

 35
Author: Jesse Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-21 04:14:02

Kolejka jest rzeczą, która akceptuje bufory poleceń zawierające operacje danego typu(podane przez flagi rodziny). Polecenia przesyłane do kolejki mają kolejność przesyłania, dlatego podlegają synchronizacji przez bariery rurociągów, zależności podrzędne i zdarzenia (podczas gdy w kolejkach musi być używany Semafor lub beter).

Jest jedna sztuczka: COMPUTE i GRAPHICS zawsze mogą domyślnie zaakceptować TRANSFER obciążenie pracą (nawet jeśli QueueFamilyProperties nie wymieniają go. Zobacz to w notatce poniżej Specyfikacja VkQueueFlagBits ).

Transfer jest dla poleceń Copy i Blit. Sparse jest czymś w rodzaju stronicowania; pozwala powiązać wiele uchwytów Pamięci do jednego obrazu, a także pozwala ponownie powiązać różne pamięci później.

W specyfikacji, poniżej podanej komendy vkCmd* zawsze jest napisane, które są "obsługiwane typy kolejek".

Rodzina kolejek to grupa kolejek, które mają szczególny związek ze sobą. Niektóre rzeczy są ograniczone do jednej kolejki Rodzina, np. obrazy (muszą być przenoszone pomiędzy rodzinami kolejek) lub Pula poleceń (tworzy bufory poleceń tylko do użycia przez daną rodzinę kolejek i nie ma innych). Teoretycznie na jakimś egzotycznym urządzeniu może być więcej rodzin kolejek z tymi samymi flagami.

To prawie wszystko, co gwarantuje Specyfikacja Vulkana. Zobacz problem z tym w KhronosGroup / Vulkan-Docs#569

Istnieją pewne materiały specyficzne dla sprzedawcy podane, np.:

[[9]}układy graficzne mają asynchroniczne silniki graficzne, Silniki obliczeniowe i silniki kopiowania\DMA. Grafika i obliczenia oczywiście konkurowałyby z tymi samymi jednostkami obliczeniowymi GPU.

Mają zwykle tylko jedną graficzną nakładkę. To jest wąskie gardło dla operacji graficznych, więc oznacza to, że nie ma wskaż użycie więcej niż jednej kolejki graficznej.

Istnieją dwa tryby pracy dla obliczeń: synchroniczne Obliczanie (narażone jako rodzina GRAPHICS|COMPUTE) i asynchroniczne Obliczanie(narażone jako rodzina COMPUTE). Pierwszy to Bezpieczny Wybór. Drugi może dać ci około 10% perf, ale jest bardziej skomplikowany i wymaga większego wysiłku. Artykuł AMD sugeruje, aby zawsze robić pierwszy jako punkt odniesienia.

Teoretycznie może być tyle kolejek obliczeniowych, ile jednostek obliczeniowych na GPU. Ale AMD argumentuje nie ma korzyści z więcej niż dwóch asynchronicznych kolejek obliczeniowych i ujawnia tyle. NVIDIA wydaje się iść z pełną liczbą.

Silniki Copy\DMA (wystawione jako rodzina TRANSFER-only) są przeznaczone przede wszystkim do transferu procesora&RLARR;GPU. Zwykle nie osiągną pełnej przepustowości dla kopii wewnątrz GPU. Więc jeśli nie ma jakiejś magii sterowników, Rodzina transferu asynchronicznego powinna być używana do transferu GPU procesora&RLARR; (aby czerpać właściwość Async, móc bez przeszkód wykonywać grafikę obok). W przypadku kopii wewnątrz-GPU w większości przypadków powinno być lepiej używać rodziny GRAPHICS|TRANSFER.

 13
Author: krOoze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-24 12:53:07