Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как уйти от постоянной проверки условия if?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
nikolas_osu
ARM-контроллер опрашивает по циклу некоторый набор блоков, перед началом цикла опроса контроллер получат команду с номерами блоков которые необходимо опрашивать в цикле. Первое что пришло в голову это опросом конкретного блока проверять по if нужно ли опрашивать данный блок. Не нравиться то что в итерациях цикла придется всегда проверять if несмотря на то что во всех итерациях условие будет одинаковым. Возможно ли обойтись без этих проверок для каждого блока в каждой итерации цикла? Язык программирования Си.
smalcom
вектор функций опроса. тебе как раз приходят индексы функций в векторе.
demiurg_spb
Массив указателей на функции блоков, а лучше массив структур с полем-флагом активности блока.

Будет один цикл с одним условием в теле цикла.
Код
block[0].active = 0;
block[1].active = 1;
....
for (int i=0; i<BLOCKS_QTY; i++)
{
   if (block[i].active)
   {
      block[i].callback();
   }
}
nikolas_osu
Цитата(smalcom @ May 13 2011, 10:27) *
вектор функций опроса. тебе как раз приходят индексы функций в векторе.

А можно поподробнее как это реализовать?

Цитата
Массив указателей на функции блоков, а лучше массив структур с полем-флагом активности блока.

Будет один цикл с одним условием в теле цикла.
Код
block[0].active = 0;
block[1].active = 1;
....
for (int i=0; i<BLOCKS_QTY; i++)
{
if (block[i].active)
{
block[i].callback();
}
}


Это совсем не то, проверка условия перед запуском опроса конкретного блока как была так и осталась, только добавились еще проверка условия цикла и вызов элемента массива.
AlexandrY
Цитата(nikolas_osu @ May 13 2011, 07:57) *
А можно поподробнее как это реализовать?

Это совсем не то, проверка условия перед запуском опроса конкретного блока как была так и осталась, только добавились еще проверка условия цикла и вызов элемента массива.


RTOS ваяете?

Номера блоков надо привести к смещению от базы до функции блока. Это делается на промежуточных константных массивах.
Как-то так wink.gif))
nikolas_osu
Цитата(AlexandrY @ May 13 2011, 13:24) *
RTOS ваяете?

Номера блоков надо привести к смещению от базы до функции блока. Это делается на промежуточных константных массивах.
Как-то так wink.gif))

Совсем нет, просто система сбора данных. Мне как-то не по душе алгоритм в котором постоянно проверяются условия, которые заведомо не меняются.

Думаю сделать через массив указателей на функции, но не знаю насколько это будет быстрее чем простой if.
Dog Pawlowa
Цитата(nikolas_osu @ May 13 2011, 10:51) *
не знаю насколько это будет быстрее чем простой if.

Не будет быстрее.
Если if оскорбляет художественный вкус, его можно куда-нить спрятать, в макрос какой-нибудь.

_Pasha
А почему только if()?
Код
do{
if(unbelievable_condition()) break;
// остальное пишем сюда
}while(0);
//тогда сразу выходим

Вы, пожалуйста, конкретизируйте вопрос детальным примером - тема-то самая "простая", опирается на построение алгоритмов sm.gif
Может, там вообще надо по другому все выводить? Например, конечным автоматом..
MrYuran
Цитата(nikolas_osu @ May 13 2011, 11:51) *
Совсем нет, просто система сбора данных. Мне как-то не по душе алгоритм в котором постоянно проверяются условия, которые заведомо не меняются.

То есть как не меняются? Константные условия?
Ну так тогда компилятор их и без вас пошинкует.
А вот прыганье по указателям очень плохо сказывается на работе конвейера и кэша (если есть).
smalcom
Цитата
А можно поподробнее как это реализовать?


Код
//объявляем
#define    CPUInstructionNum                64
void (*CPUInstructionDecodeCall[CPUInstructionNum]) (void);


Код
//инициализируем
void CPUInstructionDecoderInit()
{
uint32 i;

    for(i = 0; i < CPUInstructionNum; i++) CPUInstructionDecodeCall[i] = &CPUInvalidInstruction;
    CPUInstructionDecodeCall[CIDO_J >> CIDO_Shift] = &CPUInstructionDecodeJ;
    CPUInstructionDecodeCall[CIDO_JAL >> CIDO_Shift] = &CPUInstructionDecodeJAL;
    ...
    CPUInstructionDecodeCall[CIDO_BEQ >> CIDO_Shift] = &CPUInstructionDecodeBEQ;
}


Код
//пользуемся
void CPUInstructionDecode()
{
    (*CPUInstructionDecodeCall[CPUInstructionCurrent >> 26])();
}

смещение на 26, то только в моём случае.
ну а индексы массива это коды/опкоды приходящие из вне. у меня это, к примеру, такое
Код
enum ECPUInstructionDecoderOpcode
{
    CIDO_J = 0x08000000,
    CIDO_JAL = 0x0C000000,
    ...
    CIDO_BEQ = 0x10000000,
};



Цитата
Думаю сделать через массив указателей на функции, но не знаю насколько это будет быстрее чем простой if.

это очень быстро))
nikolas_osu
Цитата(MrYuran @ May 13 2011, 17:58) *
То есть как не меняются? Константные условия?
Ну так тогда компилятор их и без вас пошинкует.
А вот прыганье по указателям очень плохо сказывается на работе конвейера и кэша (если есть).

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

smalcom, спасибо! Это как раз то что нужно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.