Pola bitowe

0

Mam duży zestaw danych- około 6 mln próbek w dwuwymiarowej tablicy.
Żeby zmniejszyć rozmiar danych chciałbym skorzystać z pól bitowych.
Wyczytałem że nie można korzystać z tablic w polach bitowych.
Jak to obejść?

0

Pola bitowe nie slużą wcale do oszczędzania pamięci i efekty mogą być odwrotne. 6mln próbek nawet gdyby każda próbka składała się z 8bajtowych liczb to nadal jest niecałe 50MB pamięci. Zapewne masz w komputerze 4GB albo i więcej. Po co kombinować?

0

Pakietów danych jest o wiele więcej więc gra jest warta świeczki i dlatego zależy mi na tym sposobie.
Możliwe że kod spakowanych informacji i kod "dobierania się" do nich będzie krótszy.

Po kilku eksperymentach porzucam pomysł.
Temat do zamknięcia

0

Pola bitowe to po prostu nadanie poszczególnym bitom jakiś informacji/stanów, np. zamiast stosować bool, nadajesz jednemu bitowi tę informację - to w ogóle ma się nijak do oszczędzania tak dużych porcji danych, całkiem o co innego chodzi.

Najprościej skompresuj sobie to zlibem:
http://www.gamedev.pl/articles.php?x=view&id=245

  • jeśli mowa o oszczędności RAM, nie trzymaj wszystkiego w pamięci tylko pisz i czytaj aktualnie przetwarzany fragment do pliku (tak np. robią programy nagrywające dźwięk).

Więcej chyba nic nie zrobisz, cóż nie da się w magiczny sposób zmniejszyć ilości danych bez utraty jakości :>

0

Więcej chyba nic nie zrobisz, cóż nie da się w magiczny sposób zmniejszyć ilości danych bez utraty jakości :>

Moje rozwiązanie (warto zaznaczyć bezstratne):
Jako że będę pracował na 12 bitowych próbkach to będę wrzucał po dwie do struktury trzech liczb typu unsigned char(24 bity). Następnie wyliczę ze struktur współczynniki transformaty, które następnie skompresuję.

1

"niewykorzystywalnosc tablic przy polach bitowych" nie oznacza, ze w ogole nie mozesz uzywac tablic. Oznacza jedynie, ze element tablicy nie moze byc polem bitowym.
Tzn.

//majac jakies pole w stylu:
char bum : 5;
//nie mozesz "z niego" utworzyc tablicy
char (bum[15]) : 5; // to by byla jedyna opcja zapisu noszaca znamiona poprawnej skladni
char bum : 5[15]; // bezsens
char[15] bum : 5; // bezsens

po prostu nie ma zbytnio jak tego sensownie napisac..

Trzeba wiec sie postarac, aby element byl zwykly, zas pola bitowe jakos upchnac w elemencie tablicy, bedacym czyms innym, np. struktura.

drobna uwaga: http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.4
większa uwaga, dla MSVC: http://msdn.microsoft.com/en-us/library/yszfawxh(VS.80).aspx (jesli uzywasz visualstudio, przeczytaj caly ten artykul)

Biorac pod uwage ze masz pola po 12 bitow, faktycznie, dobrze upychac do 3 bajtow, albo 12 aby miec pewnosc ze zaden align-do-4B sie nie odezwie. Na szczescie w razie problemow align mozna narzucic poprzez dyrektywy kompilatora attribute-packed albo pragma-pack,1

Na przyklad:

struct bisample
{
    unsigned short sample0 : 12;
    unsigned short sample1 : 12;
} samples[1000];

//i oczywiscie
unsigned short getSample(int idx)
{
    return idx % 2 ? samples[idx/2].sample1 : samples[idx/2].sample0 ;
}

natomiast, czy bedzie ta tablica zajmowac dokladnie 10003 czy 1000(3+1) czy inna ilosc pamieci, to zalezy od tego, jak kompilator ja sobie upakuje. ustawienie attribute-packed / pragma-pack,1 spowoduje ze na pewno bedzie zajmowac 3000. oczywiscie, jesli zadbasz o to, aby pola skladaly sie na wielokrotnosc 32/64 bitow, nie bedziesz musial klopotac sie alignem. Tak czy owak, czy on wystapi, czy nie, normalne czytanie z tablicy w stylu samples[idx].sample1 zawsze odbedzie sie poprawnie, nawet jezeli nic nie bedziesz konfigurowal recznie i nawet jesli rozmiar paczki nie bedzie wielokrotnoscia szerokosci szyny. Ot, wtedy dane po cichu zajma wiecej miejsca nizby powinny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1