nanoant20 Temat założony przez niniejszego użytkownika |
użycie pragma pack » 2024-03-24 10:24:10 dostaje warning: padding struct 'Car' with 4 bytes to align 'carPrice' poczytałem i załatałem w ten sposób: #pragma pack(push) #pragma pack(4) struct Car { string carMake; string carModel; int yearModel; double carPrice; }; #pragma pack(pop)
działa, ale czy dobrze dobrałem odpowiednią wartość ? czy może argument powinien przyjąć wartość 8 ? następna rzecz to mam klasę : class Vehicle { private: string make; string model; int year; double price; vector < Vehicle > vehicles; public: };
tutaj dostaje 2 worning 1. warning: padding class 'Vehicle' with 4 bytes to align 'price' 2. warning: field vehicles within 'Vehicle' is less aligned than 'vector<Vehicle>' and is usually due to 'Vehicle' being packed, which can lead to unaligned accesses jak prawidłowo użyć dyrektywy preprocesora #pragma tego 2 worning'u w ogóle nie rozumiem testowane na: system linux Debian 12.5 64bit: int ma rozmiar 4 bajty. double ma rozmiar 8 bajty. string ma rozmiar 32 bajty |
|
DejaVu |
» 2024-03-24 10:26:39 ChatGPT 4: Wybór wartości dla dyrektywy `#pragma pack` zależy od tego, jak chcesz, aby Twoje struktury danych były wyrównane w pamięci. Ostrzeżenie, które otrzymujesz, wskazuje na to, że kompilator musiał dodać dodatkowe bajty wyrównania, aby zapewnić, że pole `carPrice` w strukturze `Car` jest odpowiednio wyrównane do granicy, która jest wymagana przez typ `double`.
### Rozmiar wyrównania
- Jeśli ustawisz `#pragma pack(4)`, oznacza to, że największy rozmiar wyrównania dla każdego pola w strukturze to 4 bajty. W przypadku typu `double`, który zwykle wymaga 8-bajtowego wyrównania, może to nie być odpowiednie, ponieważ `double` ma być wyrównany do 8 bajtów na platformach 64-bitowych, aby zapewnić optymalną wydajność dostępu. - Jeżeli ustawisz `#pragma pack(8)`, wtedy będziesz mieć wyrównanie zgodne z wymaganiami dla typu `double`, co powinno eliminować potrzebę dodawania bajtów wyrównania przed `carPrice`.
W Twoim przypadku, ponieważ `double` wymaga 8 bajtów wyrównania dla optymalnego dostępu na platformie 64-bitowej, prawidłowym wyborem byłoby użycie `#pragma pack(8)`.
### Ostrzeżenia dla klasy `Vehicle`
1. **Ostrzeżenie o wyrównaniu dla `price`**: Podobnie jak w przypadku struktury `Car`, to ostrzeżenie pojawia się, ponieważ pole `price` typu `double` wymaga 8-bajtowego wyrównania. Użycie `#pragma pack(8)` powinno również tutaj pomóc. 2. **Ostrzeżenie o mniejszym wyrównaniu dla `vehicles`**: To ostrzeżenie jest bardziej skomplikowane. Wskazuje ono na potencjalny problem z wyrównaniem pola `vehicles`, które jest typu `vector<Vehicle>`. Vektory wymagają specyficznego wyrównania, a użycie dyrektywy `#pragma pack` na klasie, która zawiera `vector`, może naruszać te wymagania, prowadząc do nieoptymalnych dostępów do pamięci lub, w najgorszym przypadku, do błędów wykonania. W związku z tym, generalnie nie zaleca się stosowania `#pragma pack` do klas lub struktur zawierających złożone typy danych, takie jak STL kontenery.
### Rozwiązania
- W przypadku prostych struktur, gdzie wydajność dostępu do pamięci jest krytyczna i jasno znasz wymagania dotyczące wyrównania, używanie `#pragma pack` może być uzasadnione. Jednak należy to robić z rozwagą, mając na uwadze wymagania dotyczące wyrównania wszystkich typów danych w strukturze. - Dla klas zawierających STL kontenery lub inne złożone typy, lepiej jest unikać używania `#pragma pack`, ponieważ może to prowadzić do problemów z wyrównaniem i wydajnością.
Zamiast stosować `#pragma pack`, zaleca się projektować klasy i struktury w taki sposób, aby naturalnie zapewniać odpowiednie wyrównanie, np. poprzez umieszczanie pól wymagających większego wyrównania na początku struktury lub klasy.
|
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-24 10:33:58 czyli podsumowując dla samej struktury mogę użyć dyrektywy `#pragma` tylko zmienić jej argument na `#pragma pack(8)` a jeżeli o klasę to ją przebudować eh. @DejaVu Dziękuję.
|
|
DejaVu |
» 2024-03-24 10:43:08 W zasadzie to ostatnia linijka jest kluczowa dla Ciebie tj. nie używaj #pragma pack w ogóle, bo nie masz projektu, który by tego wymagał. Kod powinien być maksymalnie prosty. Wydajność w typowych aplikacjach i grach poprawiasz lepszym algorytmem lub nieprocesowaniem tych samych danych wielokrotnie jeżeli da się tego nie robić, a nie mikro-optymalizacjami, które zaciemniają kod. Tak więc dopóki nie robisz sterowników pod konkretny hardware lub nie masz farmy serwerów na którym to samo oprogramowanie jest hostowane, to nie powinieneś w ogóle stosować #pragma pack w swoim kodzie. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-24 19:04:18 W zasadzie to ostatnia linijka jest kluczowa dla Ciebie dokładnie dostosowałem kod do zalecenia: Zamiast stosować `#pragma pack`, zaleca się projektować klasy i struktury w taki sposób, aby naturalnie zapewniać odpowiednie wyrównanie, np. poprzez umieszczanie pól wymagających większego wyrównania na początku struktury lub klasy. okroiłem i przebudowałem program do minimalnej formy, ale worning był dalej. Przeniosłem na inną maszynę z "Debian 11" i o dziwo skompilował się bez żadnych ostrzeżeń usunąłem "debian 12.5" i zainstalowałem "Windows 10" program się skompilował bez żadnych worning'ów pod g++ jak i Visual Stuido 2th22 z MSVC. w wersji: 1938 199711 |
|
pekfos |
» 2024-03-24 23:04:36 Wyłącz ten warning po prostu. Nie należy do typowego zestawu więc pewnie masz gdzieś dodane -Wpadded do opcji kompilatora. #pragma pack jest błędną reakcją na taki komunikat. |
|
nanoant20 Temat założony przez niniejszego użytkownika |
» 2024-03-25 08:41:14 Wyłącz ten warning po prostu. dodałem "-Wno-padded" i zadziałało @pekfos Dziękuje |
|
« 1 » |