Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#ifdef _MSC_VER # define NOINLINE __declspec(noinline) #else # define NOINLINE #endif typedef int ClassicArray[10][10][10]; typedef multi_array<int, 10, 10, 10> LukasArray; NOINLINE int Get(const ClassicArray& a, size_t x, size_t y, size_t z) { return a[x][y][z]; } NOINLINE int Get(const LukasArray& a, size_t x, size_t y, size_t z) { return a[x][y][z]; } |
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
NOINLINE int Get(const ClassicArray& a, size_t x, size_t y, size_t z) { 009F3DC0 push ebp 009F3DC1 mov ebp,esp return a[x][y][z]; 009F3DC3 mov eax,dword ptr [x] 009F3DC6 lea ecx,[eax+eax*4] 009F3DC9 mov eax,dword ptr [y] 009F3DCC lea eax,[eax+ecx*2] 009F3DCF lea ecx,[eax+eax*4] 009F3DD2 mov eax,dword ptr [z] 009F3DD5 lea ecx,[eax+ecx*2] 009F3DD8 mov eax,dword ptr [a] 009F3DDB mov eax,dword ptr [eax+ecx*4] } 009F3DDE pop ebp 009F3DDF ret |
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
NOINLINE int Get(const LukasArray& a, size_t x, size_t y, size_t z) { 009F3DF0 push ebp 009F3DF1 mov ebp,esp return a[x][y][z]; 009F3DF3 mov eax,dword ptr [x] 009F3DF6 lea ecx,[eax+eax*4] 009F3DF9 mov eax,dword ptr [y] 009F3DFC lea eax,[eax+ecx*2] 009F3DFF lea ecx,[eax+eax*4] 009F3E02 mov eax,dword ptr [z] 009F3E05 lea ecx,[eax+ecx*2] 009F3E08 mov eax,dword ptr [a] 009F3E0B mov eax,dword ptr [eax+ecx*4] } 009F3E0E pop ebp 009F3E0F ret |
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
NOINLINE int Get(const ClassicArray& a, size_t x, size_t y, size_t z) { 00322610 push ebp 00322611 mov ebp,esp return a[x][y][z]; 00322613 imul eax,dword ptr [x],190h 0032261A add eax,dword ptr [a] 0032261D imul ecx,dword ptr [y],28h 00322621 add eax,ecx 00322623 mov edx,dword ptr [z] 00322626 mov eax,dword ptr [eax+edx*4] } 00322629 pop ebp 0032262A ret ; ... NOINLINE int Get(const LukasArray& a, size_t x, size_t y, size_t z) { 00322630 push ebp 00322631 mov ebp,esp 00322633 sub esp,8 00322636 mov dword ptr [ebp-8],0CCCCCCCCh 0032263D mov dword ptr [ebp-4],0CCCCCCCCh return a[x][y][z]; 00322644 lea eax,[z] 00322647 push eax 00322648 lea ecx,[y] 0032264B push ecx 0032264C lea edx,[ebp-8] 0032264F push edx 00322650 lea eax,[x] 00322653 push eax 00322654 lea ecx,[ebp-4] 00322657 push ecx 00322658 mov ecx,dword ptr [a] 0032265B call multi_array<int,10,10,10>::operator[] (0321406h) 00322660 mov ecx,eax 00322662 call multi_array<int,10,10,10>::const_slice<10,10,10>::operator[] (032140Bh) 00322667 mov ecx,eax 00322669 call multi_array<int,10,10,10>::const_slice<10,10>::operator[] (032141Ah) 0032266E mov eax,dword ptr [eax] } 00322670 add esp,8 00322673 cmp ebp,esp 00322675 call _RTC_CheckEsp (0328F90h) 0032267A mov esp,ebp 0032267C pop ebp 0032267D ret |
Administrator
C-/C++-Quelltext |
|
1 2 3 4 5 |
struct widget { /* big data here ... */ }; std::vector<widget> container(1000); |
C-/C++-Quelltext |
|
1 2 |
struct widget { /* like above */ }; std::vector<std::unique_ptr<widget>> container(1000); |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
struct A { virtual ~A() { } int x = 1; }; struct B : public A { int y = 2; }; struct C { int z = 3; }; packed_vector<A> container; // Add elements container.push_back(A()); container.push_back(B()); // Access these elements auto a = container.get<A>(0); auto b = container.get<B>(1); auto b_as_a = container.get<A>(1); auto c = container.get<C>(1); // ERROR (static_assert) -> 'C' is not a base of 'A' (std::is_base_of), ERROR -> 2nd element is of type 'B' and 'C' |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »LukasBanana« (19.10.2014, 15:54)
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <iostream> #include "packed.hpp" struct BaseA { virtual ~BaseA() {}; int ba_x; }; struct BaseB { virtual ~BaseB() {}; int bb_x; }; struct DerivedB : public BaseB, public BaseA { int db_x; }; int main() { ext::packed_vector<BaseA> list; list.push_back(DerivedB()); DerivedB derived; BaseA* ptr = &derived; DerivedB* ptr2 = dynamic_cast<DerivedB*>(ptr); if (!ptr2) { std::cerr << "Error: ptr2 == nulltpr\n"; } else if (ptr2 != &derived) { std::cerr << "Error: ptr wrong value\n"; } DerivedB* ptr3 = list.get_ptr<DerivedB>(0); if (!ptr3) { std::cerr << "Error: ptr3 == nulltpr\n"; } } |
Quellcode |
|
1 2 |
~ % clang++ -std=c++11 -g test_multi2.cpp && ./a.out Error: ptr3 == nulltpr |
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 |
packed_vector<BaseA> list; // Vorher: struct DerivedB : public BaseB, public BaseA // Nachher: struct DerivedB : public BaseA, public BaseB |
C-/C++-Quelltext |
|
1 2 |
Derived d; // Basisklasse: Base (void*)&d == (void*)((Base*)&d); |
Zitat von »"C++ Standard: §10 Abs 5"«
The order in which the base class subobjects are allocated in the most derived object is unspecified.
Hast du mal realistische Benchmarks dazu gemacht?
Klingt für mich nicht unbedingt deutlich effizienter als die alte Variante.
Zitat von »"C++ Standard: §10 Abs 5"«
The order in which the base class subobjects are allocated in the most derived object is unspecified.
Es können also sehr gut erst die abgeleiteten Member im Speicher kommen und dann die der Basisklasse.
C-/C++-Quelltext |
|
1 2 3 4 5 |
#if defined(_MSC_VER) __msvc_compiler_specific_keyword_about_polymorphic_storage_management(...) #elif defined(GNUC) ... #endif |
C-/C++-Quelltext |
|
1 2 3 4 |
struct S { std::unique_ptr<int> i; } |
Werbeanzeige