Lesson 21. Pattern 13. Data alignment


Published on

Processors work more efficiently when the data are aligned properly and some processors cannot work with non-aligned data at all.

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Lesson 21. Pattern 13. Data alignment

  1. 1. Lesson 21. Pattern 13. Data alignmentProcessors work more efficiently when the data are aligned properly and some processors cannot workwith non-aligned data at all. When you try to work with non-aligned data on IA-64 (Itanium) processors,it will lead to generating an exception, as shown in the following example:#pragma pack (1) // Also set by key /Zp in MSVCstruct AlignSample { unsigned size; void *pointer;} object;void foo(void *p) { object.pointer = p; // Alignment fault}If you have to work with non-aligned data on Itanium, you should specify this explicitly to the compiler.For example, you may use a special macro UNALIGNED:#pragma pack (1) // Also set by key /Zp in MSVCstruct AlignSample { unsigned size; void *pointer;} object;void foo(void *p) { *(UNALIGNED void *)&object.pointer = p; //Very slow}In this case the compiler generates a special code to deal with the non-aligned data. It is not veryefficient since the access to the data will be several times slower. If your purpose is to make thestructures size smaller, you can get the best result arranging the data in decreasing order of their sizes.We will speak about it in more detail in one of the next lessons.Exceptions are not generated when you address non-aligned data on the architecture x64 but you stillshould avoid them - first, because the access to these data is very much slower, and second, becauseyou may want to port the program to the platform IA-64 in the future.Consider one more code sample that does not consider the data alignment:struct MyPointersArray { DWORD m_n;
  2. 2. PVOID m_arr[1];} object;...malloc( sizeof(DWORD) + 5 * sizeof(PVOID) );...If we want to allocate an amount of memory needed to store an object of MyPointersArray type thatcontains 5 pointers, we should consider that the beginning of the array m_arr will be aligned on an 8-byte boundary. The arrangement of data in memory in various systems (Win32/Win64) is shown inFigure 1. Figure 1- Data alignment in memory in Win32 and Win64 systemsThe correct calculation of the size looks as follows:struct MyPointersArray { DWORD m_n; PVOID m_arr[1];} object;...malloc( FIELD_OFFSET(struct MyPointersArray, m_arr) + 5 * sizeof(PVOID) );...
  3. 3. In this code we find out the offset of the structures last member and add this value to its size. You canfind out the offset of a structures or classs member with the help of the macro "offsetof" orFIELD_OFFSET.Always use these macros to know the offset in the structure without relying on knowing the types sizesand alignment. Here is an example of code where the address of a structures member is calculatedcorrectly:struct TFoo { DWORD_PTR whatever; int value;} object;int *valuePtr = (int *)((size_t)(&object) + offsetof(TFoo, value)); // OKLinux-developers may encounter one more trouble related to alignment. You may learn what it is fromour blog-post "Change of type alignment and the consequences".DiagnosisSince work with non-aligned data does not cause an error on the x64 architecture and only reducesperformance, the tool PVS-Studio does not warn you about packed structures. But if the performance ofan application is crucial to you, we recommend you to look through all the fragments in the programwhere "#pragma pack" is used. This is more relevant for the architecture IA-64 but PVS-Studio analyzeris not designed to verify programs for IA-64 yet. If you deal with Itanium-based systems and are planningto purchase PVS-Studio, write to us and we will discuss the issues of adapting our tool to IA-64 specifics.PVS-Studio tool allows you to find errors related to calculation of objects sizes and offsets. The analyzerdetects dangerous arithmetic expressions containing several operators sizeof() (it signals a potentialerror). The number of the corresponding diagnostic message is V119.However, it is correct in many cases to use several sizeof() operators in one expression and the analyzerignores such constructs. Here is an example of safe expressions with several sizeof operators:int MyArray[] = { 1, 2, 3 };size_t MyArraySize = sizeof(MyArray) / sizeof(MyArray[0]); //OKassert(sizeof(unsigned) < sizeof(size_t)); //OKsize_t strLen = sizeof(String) - sizeof(TCHAR); //OK
  4. 4. AppendixFigure 2 represents types sizes and their alignment. To learn about objects sizes and their alignment onvarious platforms, see the code sample given in the blog-post "Change of type alignment and theconsequences". Figure 2 - Types sizes and their alignment.The course authors: Andrey Karpov (karpov@viva64.com), Evgeniy Ryzhkov (evg@viva64.com).The rightholder of the course "Lessons on development of 64-bit C/C++ applications" is OOO "ProgramVerification Systems". The company develops software in the sphere of source program code analysis.The companys site: http://www.viva64.com.
  5. 5. Contacts: e-mail: support@viva64.com, Tula, 300027, PO box 1800.