Lang verhaal: In een critical section heb ik een insert in een Stack< .. , std::vector< .. > > staan. Wanneer de vector moet reallocaten ben je langer in die critical section dan gewenst. Mijn oplossing: maak je eigen stack welke een wrapper om std::vector is. reserve() 10.000 elementen or-so, noem dat een link, wanneer de link vol is maak je een nieuwe link aan. Dit noemen we een EfficientStack en bevat intern een vector van link's (wat dus ook weer een vector is).
In feite is er natuurlijk niets 'efficient' aan, behalve dat de wordt-case insertion time wat beter is.
Strikvraag: hoeveel elementen per link is optimaal? Met 1000 elementen duurt het vrijgeven veel langer dan bij 100 of 10000 elementen. Dat vraagt om meer onderzoek.
testcase ( download. De testcase pakt ~3GB aan data, als je hem als 32-bit app compileet moet je de count in main() wat tweaken. Maar het effect neemt erg af naarmate de datastructuur kleiner wordt.)
data. X-as = aantel items per link. Y-as = tijd in ms. De eerste grafiek is logaritmisch.

Gecompileerd onder: msvc 2012 x64. MinGW laat vergelijkbare resultaten zien.
Concrete vraag: hoe kan het dat het vrijgeven van een array van 342 items zo veel langer duurt dan het vrijgeven van 341 items? Overigens is het performanceverschil nog minstens 10x zo groot bij het gebruik van mijn multithreaded deleter.
Waarschijnlijk heeft het iets te maken met de hoeveelheid cache. één Item is 48 bytes. 48 * 341 = 16368. Maar hoe kan dat er nu weer voor zorgen dat het destructen van data meer dan 3 maal zo lang duurt terwijl er nauwelijks impact te zien is in het constructen van de elementen?
Rauwe data (tijd van destruction)
In feite is er natuurlijk niets 'efficient' aan, behalve dat de wordt-case insertion time wat beter is.
Strikvraag: hoeveel elementen per link is optimaal? Met 1000 elementen duurt het vrijgeven veel langer dan bij 100 of 10000 elementen. Dat vraagt om meer onderzoek.
testcase ( download. De testcase pakt ~3GB aan data, als je hem als 32-bit app compileet moet je de count in main() wat tweaken. Maar het effect neemt erg af naarmate de datastructuur kleiner wordt.)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| class Item { public: Item( int n ) { foo = new int[ n ]; } Item( Item&& other ) { foo = other.foo; other.foo = 0; } ~Item() { delete foo; } int* foo; int bar[9]; // some filler data.. }; |
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| int count = 30 miljoen ofzo. QTime time; time.restart(); { EfficientStack< Item > stack( size ); // size = hoeveel items er in één link gaan. for( int i = 0; i < count; i++ ) { stack.push( Item( 5 ) ); // 'random' getal. } timeEnqueue += time.elapsed(); time.restart(); } // let stack go out of scope timeDestroy += time.elapsed(); |
data. X-as = aantel items per link. Y-as = tijd in ms. De eerste grafiek is logaritmisch.

Gecompileerd onder: msvc 2012 x64. MinGW laat vergelijkbare resultaten zien.
Concrete vraag: hoe kan het dat het vrijgeven van een array van 342 items zo veel langer duurt dan het vrijgeven van 341 items? Overigens is het performanceverschil nog minstens 10x zo groot bij het gebruik van mijn multithreaded deleter.
Waarschijnlijk heeft het iets te maken met de hoeveelheid cache. één Item is 48 bytes. 48 * 341 = 16368. Maar hoe kan dat er nu weer voor zorgen dat het destructen van data meer dan 3 maal zo lang duurt terwijl er nauwelijks impact te zien is in het constructen van de elementen?
Rauwe data (tijd van destruction)
| test 1 ( 2 x ) | test 2 ( 256 ... 512 ) | test 3 ( 336 ... 352 ) | |||
|---|---|---|---|---|---|
| N | tijd (in ms) | N | tijd (in ms) | N | tijd (in ms) |
| 2 | 2500 | 256 | 1187 | 336 | 1172 |
| 4 | 1605 | 272 | 1250 | 337 | 1235 |
| 8 | 1375 | 288 | 1262 | 338 | 1250 |
| 16 | 1312 | 304 | 1141 | 339 | 1125 |
| 32 | 1234 | 320 | 1297 | 340 | 1234 |
| 64 | 1391 | 336 | 1360 | 341 | 1328 |
| 128 | 1359 | 352 | 3844 | 342 | 3657 |
| 256 | 1375 | 368 | 3891 | 343 | 3688 |
| 512 | 3937 | 384 | 3625 | 344 | 3730 |
| 1024 | 3844 | 400 | 3750 | 345 | 3750 |
| 2048 | 3376 | 416 | 3641 | 346 | 3828 |
| 4096 | 1672 | 432 | 3610 | 347 | 3667 |
| 8192 | 1344 | 448 | 3766 | 348 | 3657 |
| 16384 | 1235 | 464 | 3734 | 349 | 3829 |
| 32768 | 1171 | 480 | 3906 | 350 | 3750 |
| 65536 | 1251 | 496 | 3938 | 351 | 3687 |
| 512 | 3687 | 352 | 3750 | ||