Какой самый быстрый способ перебрать большой кусок данных для каждого бита - PullRequest
2 голосов
/ 07 января 2009

Я выполняю блок памяти двоичных данных побайтно.

В настоящее время я делаю что-то вроде этого:

for (i = 0; i < data->Count; i++)
{   
    byte = &data->Data[i];
    ((*byte & Masks[0]) == Masks[0]) ? Stats.FreqOf1++; // syntax incorrect but you get the point.
    ((*byte & Masks[1]) == Masks[1]) ? Stats.FreqOf1++;
    ((*byte & Masks[2]) == Masks[2]) ? Stats.FreqOf1++;
    ((*byte & Masks[3]) == Masks[3]) ? Stats.FreqOf1++;
    ((*byte & Masks[4]) == Masks[4]) ? Stats.FreqOf1++;
    ((*byte & Masks[5]) == Masks[5]) ? Stats.FreqOf1++;
    ((*byte & Masks[6]) == Masks[6]) ? Stats.FreqOf1++;
    ((*byte & Masks[7]) == Masks[7]) ? Stats.FreqOf1++;
}

Где Маски:

for (i = 0; i < 8; i++)
{
    Masks[i] = 1 << i;
}

(Мне как-то не удалось сделать это так быстро в цикле или во встроенной функции, поэтому я выписал это.)

У кого-нибудь есть предложения по улучшению этого первого цикла? Я довольно неопытен, чтобы разбираться с этим.

Это может показаться глупостью. Но я нахожусь в процессе реализации алгоритма сжатия. Я просто хочу получить доступ к части внизу справа.

Спасибо!

PS: это в компиляторе Visual Studio 2008. Поэтому было бы неплохо, если бы предложения применялись к этому компилятору.

PPS: Я только что понял, что мне не нужно увеличивать два счета. Одного было бы достаточно. Затем вычислите разницу в общем количестве бит в конце. Но это было бы просто для подсчета. Что я действительно хочу сделать быстро, так это извлечение битов.

EDIT: Идея таблицы поиска, которая была выдвинута, хороша. Однако я понимаю, что поставил вопрос неправильно в названии. Потому что в итоге я хочу не считать биты, а получить доступ к каждому биту как можно быстрее.

ДРУГОЕ РЕДАКТИРОВАНИЕ: Можно ли продвинуть указатель на один бит в данных?

ДРУГОЕ РЕДАКТИРОВАНИЕ: Спасибо за все ваши ответы.

То, что я хочу реализовать на следующих шагах, - это сложный двоичный арифметический кодер, который не анализирует контекст. Так что меня сейчас интересуют только отдельные биты. В конце концов он станет контекстно-адаптивным BAC, но я оставлю это на потом.

Возможна обработка 4 байта вместо 1 байта. Но цикл с 32 битами также дорог, не так ли?

Ответы [ 12 ]

0 голосов
/ 07 января 2009

Если это не случай преждевременной оптимизации, и вам действительно нужно выжать каждую последнюю фемтосекунду, то вам, вероятно, лучше использовать статический массив из 256 элементов, который вы заполняете один раз счетчиком битов каждого значения байта. тогда

Stats.FreqOf1 + = bitCountTable [byte]

и когда цикл завершен:

Stats.FreqOf0 = ((data-> Count * 8) - Stats.FreqOf1)

0 голосов
/ 07 января 2009

Чтобы присоединиться к ссылке вагон: счетные биты

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...