Чтение данных из битового потока

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Inkognito
Сообщения: 4
Зарегистрирован: 15 фев 2005, 16:04
Откуда: Магадан
Контактная информация:

Здравствуйте.

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

Суть функции

Код: Выделить всё

inline short readbits( unsigned char *p, short from, short cnt )
{

}
нужна функция типа substr для битов...
т.е. readbits( p, 14, 16 ) значит прочти 16 битов начиная с десятого...чтение начинается со 1-ого байта (10 бит 14 / 8 = 1) p[1] и продолжаеться до p[3]

Ассемблер не предлагать
Что можно с этим сделать???
Да, и еще одно ограничение...больше 16-и битов читаться не будет...это максимальное количество...функция возвращяет short.
Заранее спасибо...
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Ты бы показал код имеющейся реализации функции, чтобы другим не повторять то же самое.
Inkognito
Сообщения: 4
Зарегистрирован: 15 фев 2005, 16:04
Откуда: Магадан
Контактная информация:

Она в классе, ее оттуда вытаскивать будет сложновато...Имеющееся функция работает примерно так...

Есть одна функция которая методом shift-а получает один бит из данного потока... << 7 - nBitNumber потом >> 7
Есть другая функция которая уже знаю количество читаемых битов в цикле вызывает
int ret = 0;
for (int i = 0; i < nBitCount; ++i)
{
ret <<= 1;
ret |= ReadBit();
}
Что то вроде этого...теперь я решил убрать классы, писать на макросах и инлайн функциях...и для этого нужна вот эта функция...
Заодно скажу что моя программа работала примерно 0.1 секунду под линукс на обычном интел пентиум...но работать она будет на процессоре 80Mhz...И стала она там работать примерно 18 секунд...надо повысить производительность примерно в 20 раз...как? понятия не имею но эта функция тормозит программу примерно на 10 секунд...если ее подправить и немного оптимизировать код думаю все получится...
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Думаю, оптимизировать если и можно, то точно не в 20 раз. Приведённый for вообще оптимизации не поддаётся: две логические операции - быстрее их не будет работать ничто. Всё упирается в реализацию ReadBit, которая не приведена. Если и ReadBit написана достаточно оптимально могу подсказать лишь небольшую оптимизацию: проверять сколько нужно прочесть бит. Если меньше восьми - использовать текущий алгоритм, если больше восьми, то будет быстрее взять из потока целый short, а потом сдвинуть его вправо.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Честно говоря, мне влом это отлаживать. Давай сам.

Идея такая: from>>3 это деление на восемь
from & 07 это остаток от деления на восемь
unsigned int *iptr = (unsigned int *)(p + (from>>3) ); Загружаем весь кусок в 32-битовую переменную. На Блок битов с максимальной длиной 16 этого хватит по любому.

*iptr<<(from & 07) Выравниваем блок бит относительно левого края 32-х битовой переменной
xxx >> (32 - cnt) Сдвигаем его вправо в область младших бит, туда где он должен быть.
(short)(xxx) Откусываем ненужное.

inline short readbits( unsigned char *p, short from, short cnt )
{
unsigned int *iptr = (unsigned int *)(p + (from>>3) );
return (short)((*iptr<<(from & 07))>>(32 - cnt));
}
теперь я решил убрать классы, писать на макросах и инлайн функциях...и для этого нужна вот эта функция...
Бесполезно. Классы сами по себе ничего не замедляют. Видел Демы на Java? А в Java вообще без классов нельзя, и все методы- виртуальные.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

P.S Если в функции есть цикл, от компилятор обычно игнорирует квалификатор inline
2B OR NOT(2B) = FF
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Можно обойтись без операторов сдвига(<<) и цикла(for), или свести их к минимуму.
Для получения значения отдельно взятого бита в слове или отдельном байте можно использовать битовые поля, а для выделения некоторого количества бит из байта или целого слова можно применить так называемые битовые маски.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Ассемблерная реализации С++ битовых полей - есть логические операции над словами. Так что логических операций не избежать :) Разве что в явном виде.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Inkognito
Сообщения: 4
Зарегистрирован: 15 фев 2005, 16:04
Откуда: Магадан
Контактная информация:

Добавлено: 16.02.05 12:14 Заголовок сообщения:



Честно говоря, мне влом это отлаживать. Давай сам.

Идея такая: from>>3 это деление на восемь
from & 07 это остаток от деления на восемь
unsigned int *iptr = (unsigned int *)(p + (from>>3) ); Загружаем весь кусок в 32-битовую переменную. На Блок битов с максимальной длиной 16 этого хватит по любому.
Вообще то примерно что то подобное я сделал, но так это не работает...int переворачивает байты. так что *iptr = (unsigned int *)(p + (from>>3) ); работать не станет...
Думаю, оптимизировать если и можно, то точно не в 20 раз. Приведённый for вообще оптимизации не поддаётся: две логические операции - быстрее их не будет работать ничто. Всё упирается в реализацию ReadBit, которая не приведена. Если и ReadBit написана достаточно оптимально могу подсказать лишь небольшую оптимизацию: проверять сколько нужно прочесть бит. Если меньше восьми - использовать текущий алгоритм, если больше восьми, то будет быстрее взять из потока целый short, а потом сдвинуть его вправо.
Я не про оптимизацию этого кода, надо написать новый...этот разумеется оптимизировать нельзя...а если и можно то уж точно не в 20 раз и даже не в два раза...алгоритм новый нужен...

у меня сейчас что то написано, но не очень то хорошо работает...

Код: Выделить всё

unsigned short _mask[17] = {
		0x0000,
		0x0001,
		0x0003,
		0x0007,
		0x000f,
		0x001f,
		0x003f,
		0x007f,
		0x00ff,
		0x01ff,
		0x03ff,
		0x07ff,
		0x0fff,
		0x1fff,
		0x3fff,
		0x7fff,
		0xffff
};
inline unsigned short bitCapture( unsigned char *p, short from, short cnt )
{
	unsigned int buffIndex = from >> 3;
	unsigned int reg32 = ( (p[buffIndex] << 16) | (p[buffIndex + 1] << 8) | p[buffIndex + 2] );
	return ( reg32 >> ( ( 32 - ( (from - buffIndex * 8) + 8 ) ) - cnt ) ) & _mask[ cnt ];
}
Inkognito
Сообщения: 4
Зарегистрирован: 15 фев 2005, 16:04
Откуда: Магадан
Контактная информация:

Заставил эту функцию заработать (вместо 32х там 31)
Но один вопрос остался...то ли я чего то не понял, то ли что то в самом деле не так...
Например у меня в файле есть такие данные
1byte 2byte
00111010 11001001

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

Это T4, Факс G3 формат..конвертирую в TIFF
Ответить