2016-08-09 2 views
2

Im Vulkan-Header vulkan.h gibt es eine Struktur definiertWas ist der Grund für die Ausrichtung dieser Struktur?

typedef struct VkSwapchainCreateInfoKHR { 
    VkStructureType     sType; 
    const void*      pNext; 
    VkSwapchainCreateFlagsKHR  flags; 
    VkSurfaceKHR      surface; 
    uint32_t       minImageCount; 
    VkFormat       imageFormat; 
    VkColorSpaceKHR     imageColorSpace; 
    VkExtent2D      imageExtent; 
    uint32_t       imageArrayLayers; 
    VkImageUsageFlags    imageUsage; 
    VkSharingMode     imageSharingMode; 
    uint32_t       queueFamilyIndexCount; 
    const uint32_t*     pQueueFamilyIndices; 
    VkSurfaceTransformFlagBitsKHR preTransform; 
    VkCompositeAlphaFlagBitsKHR  compositeAlpha; 
    VkPresentModeKHR     presentMode; 
    VkBool32       clipped; 
    VkSwapchainKHR     oldSwapchain; 
} VkSwapchainCreateInfoKHR; 

ich den folgenden Code verwendet haben jedes Feld der Ausrichtung (Visual Studio 2015) diese Ergebnisse

std::cout << 
     "sType: " << offsetof(VkSwapchainCreateInfoKHR, sType) << std::endl << 
     "pNext: " << offsetof(VkSwapchainCreateInfoKHR, pNext) << std::endl << 
     "flags: " << offsetof(VkSwapchainCreateInfoKHR, flags) << std::endl << 
     "surface: " << offsetof(VkSwapchainCreateInfoKHR, surface) << std::endl << 
     "minImageCount: " << offsetof(VkSwapchainCreateInfoKHR, minImageCount) << std::endl << 
     "imageFormat: " << offsetof(VkSwapchainCreateInfoKHR, imageFormat) << std::endl << 
     "imageColorSpace: " << offsetof(VkSwapchainCreateInfoKHR, imageColorSpace) << std::endl << 
     "imageExtent: " << offsetof(VkSwapchainCreateInfoKHR, imageExtent) << std::endl << 
     "imageArrayLayers: " << offsetof(VkSwapchainCreateInfoKHR, imageArrayLayers) << std::endl << 
     "imageUsage: " << offsetof(VkSwapchainCreateInfoKHR, imageUsage) << std::endl << 
     "imageSharingMode: " << offsetof(VkSwapchainCreateInfoKHR, imageSharingMode) << std::endl << 
     "queueFamilyIndexCount: " << offsetof(VkSwapchainCreateInfoKHR, queueFamilyIndexCount) << std::endl << 
     "pQueueFamilyIndices: " << offsetof(VkSwapchainCreateInfoKHR, pQueueFamilyIndices) << std::endl << 
     "preTransform: " << offsetof(VkSwapchainCreateInfoKHR, preTransform) << std::endl << 
     "compositeAlpha: " << offsetof(VkSwapchainCreateInfoKHR, compositeAlpha) << std::endl << 
     "presentMode: " << offsetof(VkSwapchainCreateInfoKHR, presentMode) << std::endl << 
     "clipped: " << offsetof(VkSwapchainCreateInfoKHR, clipped) << std::endl << 
     "oldSwapchain: " << offsetof(VkSwapchainCreateInfoKHR, oldSwapchain) << std::endl << 
     std::endl; 

Und zu sehen bekam

sType: 0 
pNext: 8 
flags: 16 
surface: 24 
minImageCount: 32 
imageFormat: 36 
imageColorSpace: 40 
imageExtent: 44 
imageArrayLayers: 52 
imageUsageFlags: 56 
imageSharingMode: 60 
queueFamilyIndexCount: 64 
pQueueFamilyIndices: 72 
preTransform: 80 
compositeAlpha: 84 
presentMode: 88 
clipped: 92 
oldSwapchain: 96 

Zwischen den Feldern flags und surface gibt es eine 8-Byte-Lücke, eve n obwohl flags einen zugrunde liegenden Typ von uint32_t hat. Das Gleiche gilt für die Felder und pQueueFamilyIndices. Warum nehmen flags und 8 Bytes auf, wenn sie nur 4 Bytes breit sind und jedes andere Feld vom Typ uint32_t nur 4 Bytes belegt? Gibt es etwas Besonderes bezüglich der Speicherausrichtungsanforderungen bei diesen Offsets?

+2

Polsterung ......................... –

+0

Aber warum werden nur diese Felder gepolstert? Beide sind um ein Vielfaches von 16 versetzt, warum sollte also das nächste Feld aufgefüllt werden? – rhynodegreat

+2

@ πάνταῥεῖ Er, nett. :) –

Antwort

4

VkSurfaceKHR ist ein nicht ausrichtbarer Handle. Was nach den Definitionen von Vulkan eine 64-Bit-Ganzzahl ist. Und deshalb muss es 8-Byte-Ausrichtung haben.

Wenn Strukturen erstellt werden, stellt der Compiler sicher, dass jedes Element die Ausrichtung erhält, die der Typ erfordert. Wenn surface unmittelbar nach flags gekommen wäre, hätte es keine 8-Byte-Ausrichtung. Somit fügt der Compiler zwischen den beiden 4 Bytes Padding ein.

+0

Das Problem ist, dass 'Flags '8 Bytes belegen. – rhynodegreat

+6

@rhynodegreat: Nein, ist es nicht. Es dauert 4 Bytes. Es folgen vier * unbrauchbare Bytes *, so dass das nächste Feld 8-Byte-ausgerichtet sein kann. –

+1

Ah, also wird das Padding hinzugefügt, weil das nächste Feld 8 Byte groß ist und ausgerichtet werden muss. Gleiches mit 'queueFamilyIndexCount', auf das ein Zeiger folgt. – rhynodegreat

1

Alle Typen haben eine Größe sizeof(T), und eine Ausrichtung Anforderung alignof(T). Instanzen davon müssen immer im Speicher an Adressen angeordnet werden, die ein Vielfaches von alignof(T) sind.

in einer Struktur, fügt der Compiler automatisch padding zwischen den Elementen, so dass dieses Erfordernis für alle seine Elemente erfüllt ist, relativ zu der Startadresse des struct (das heißt für die offsetof Werte). Dies ist ein leerer Platz zwischen nachfolgenden Strukturelementen.

Es setzt auch die alignof der gesamten Struktur, so dass alle seine Elemente korrekt im Speicher ausgerichtet werden. Zum Beispiel auf einer typischen 64-Bit-Plattform:

struct A { 
    char c; // sizeof(char) == 1; alignof(char) == 1 
    int* ptr; // sizeof(char) == 8; alignof(char) == 8 
} 

Pointers hat eine Größe von 8 Byte (64 Bit), sowie eine Ausrichtungsanforderung von 8 Byte. In dieser Struktur gibt es 7 Byte Auffüllung zwischen c und ptr, so dass offsetof(A, c) == 0 und offsetof(A, ptr) == 8. Und alignof(A) == 8. Immer wenn eine Instanz A a erstellt wird (auf Stapel oder auf Heap), &a % 8 == 0, und so &(a.ptr) % 8 == 0.


Nachdem dies geschehen ist, weil einige CPU-Anweisungen (zum Beispiel Vektorbefehle SIMD) ihre Operanden erfordern, an Wortgrenzen ausgerichtet sein, das heißt ein Vielfaches von 8 (oder 4 für 32-Bit) in den Speicher. Ohne die richtige Ausrichtung könnten diese Anweisungen nicht direkt verwendet werden und das Programm würde langsamer werden.


In diesem Beispiel VkSurfaceKHR und pQueueFamilyIndices sind Zeiger mit alignof == 8.

+0

können Sie den leeren Raum verwenden – Tibrogargan

Verwandte Themen