State_Maschine

enum {S0=0, S1, S2, S3, S4...} state;

Точно.

Reply to
Kirill Frolov
Loading thread data ...

Ещё интересный вариант -- указатель на функцию-состояние. Впрочем, я склоняюсь к тому, чтобы иметь состояние представимое в числовом виде (как в случае с switch-case) и дополнительно указатель на функцию, для быстрого выбора нужного состояния (первое нужно для просверки состояния в других автоматах, а действия в разных состояниях могут быть объединены в одну функцию). Плюс нужен какой-то планировщик для запуска автоматов. Иначе неэффективно, тратится масса времени на бесполезные проверки условий переходов.

Reply to
Kirill Frolov

Здравствуйте, Уважаемый Nicolas!

Tue Jul 04 2006 19:12, Nicolas Minakov wrote to Olga Nonova:

NM> Ольга, так а что у Вас получилось?

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

NM> Чем компилировали? Под какой камень? Тут достаточно квалифицированных NM> людей, чтоб помочь, конечно если оно Вам действительно нужно.

Спасибо на добром слове. А то я уже отчаялась получить в ответ что-либо, кроме бессмысленного хамства. Работаю я с MCF5270 "ColdFire", это из серии 68K от FreeScale. Пакет разработки на С++ от GNU. И я столкнулась с проблемой, что в С++ (не только в GNU компайлере!) оператор switch производит перебор всех case-ов, пока не произойдет сравнение с искомым. Та-же история и в Дельи. Внимание, вопрос: Какие есть варианты реализовать в С++ или Дельфях максимально эффективное ветвление, чтоб без перебора и без ограничений на тип выражения case-ов?

Всего Вам Хорошего Ольга

Reply to
Olga Nonova
Reply to
Anatoly Mashanov

Афтары зажигают аж жуть. Во-первых не всех. А вплоть до log2(N). А во вторых есть и табличный метод. И наконец -O3 -Wall и -S в студию.

Reply to
Kirill Frolov
Reply to
Nickita A Startcev
Reply to
Nickita A Startcev

Здравствуйте, Уважаемый Slav!

Wed Jul 05 2006 12:48, Slav Matveev wrote to Olga Nonova:

ON>> switch (SomeChar) { ON>> case 'A': Do_A(); break; ON>> case 'B': Do_B(); break; ON>> default: Dо_Default(); break; ON>> }

ON>> Допустима в С (без плюсов) такая конструкция из значений case-ов? И ON>> что компильнет компилятор- тоже очень интересно.

SM> сударыня! на

formatting link
раздают забесплатно неплохой SM> компилятор С/С++. Почему бы вам не заиметь себе компилятор и SM> не поэкспериментировать в какой ассемблерный код какой SM> исходный текст преобразуется? SM> Может быть на понимание вас натолкнет ругань SM> комплятора: case label does not reduce to an integer constant ?

SM> Ваш же детский лепет транслируется в код:

SM> movb SomeChar, %al SM> movsbl %al,%eax SM> movl %eax, -4(%ebp) SM> cmpl $65, -4(%ebp) SM> je .L3 SM> cmpl $66, -4(%ebp) SM> je .L4 SM> jmp .L2 SM> .L3: SM> call Do_A SM> jmp .L5 SM> .L4: SM> call Do_B SM> jmp .L5 SM> .L2: SM> call Do_Default SM> .L5:

Иными словами, видим полный перебор case-ов. Что и требовалось доказать.

SM> В случае с большим количеством case'ов в менее красивый код SM> с jmp'ом по таблице.

Да-да, речь идет именно о количестве case-ов в районе десятка. И как же тогда получить "красивый код" с таблицей jmp-ов, если выражение при switch не дает, как я Вам представила на примере, регулярных значений из ряда 0,1,2...? Hикак этого у Вас не получится, а по-прежнему будет тухлый перебор всех подряд.

Если действительно только Do_A(), а не SM> { ... } в ассемблере можно было бы обойтись call'ом по таблице. SM> но никто не мешает вместо такого swtich'а сделать массив SM> указателей на функции и вызывать функцию по индексу SomeChar-'A'.

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

//Вот три макроса для построения любой State_Machine.

#define StateMachine(MyName) void(*MyName)() #define ExecStateOf(StateMachine) (*StateMachine)() #define SetState(StateMachine,NewState) StateMachine=NewState;

//Среди переменных задачи декларируете указатель

StateMachine(SM);

//И пишете действия в состояниях в виде функций, например, их три штуки void State3() {/*DoSomthing3*/;} void State2() {/*DoSomthing2*/;} void State1() {/*DoSomthing1*/;}

//Затем в исполняемых кодах инициализируете конечный автомат SetState(SM,State1); // и приступаете к циклическим вызовам его действий ExecStateOf(SM); //Внутри этих действий Вам не возбраняется переключать состояния SetState(SM,StateN);

У меня, к сожалению, не получается получить ассемблерный текст watcom-овского компилятора. Может Вы попробуете оценить эффективность такого решения? Hиже полный исходный текст консольного приложения для C++. Сколько в нем занимает выполнение непосредственно ExecStateOf(SM)? Была бы чрезвычайно благодарна.

Всего Вам Хорошего Ольга

#include <iostream>

#include <stdlib.h>

#define StateMachine(MyName) void(*MyName)() #define ExecStateOf(StateMachine) (*StateMachine)() #define SetState(StateMachine,NewState) StateMachine=NewState;

using namespace std;

StateMachine(SM);

void State3() {cout << "3" << endl;} void State2() {cout << "2" << endl; SetState(SM,State3);} void State1() {cout << "1" << endl; SetState(SM,State2);}

int main(int argc, char *argv[]) { SetState(SM,State1); ExecStateOf(SM); ExecStateOf(SM); ExecStateOf(SM);

system("PAUSE"); return 0; }

Reply to
Olga Nonova

С чего бы это? Строковые константы представимы как целые с соответствующим ASCII кодом...

Reply to
Kirill Frolov

Не полный, а до первого совпадения. Что это доказывает -- я не знаю. Но умаю, что ничего.

Компилятр в отличии от вас не дурак и понимает, что в случае небольшого числа вариантов таблица -- неоптимальный вариант.

Думаешь, если Писать В дРеБезЖащёМ рГисТРе -- оно лучше заработает? Вот что хуже -- точно. Я даже скажу почэему -- макрос не отличить от функции.

Поная ерунда. В Keil для x51 замучаешься ручками (придётся тки скрипт написать) линкерный файл править, догадайся для чего... Плс я уже писал

-- числовой номер он важен и первичен. А это -- лишь мето д оптимизации.

Обязательно в дребезжащем регистре. А то не заработает! И ещё незабудьте озаботиться вопросом области видимости переменных вашего автомата.

При этом он уже выполняет переход из /неизвестного состояния/ в первое. Ключевое слово -- неизвестного.

^^^^^^^^^^

Вас так беспокоил десяток-другой тактов на switch-case?

formatting link
Там проделана достаточно большая работа.

Это не C++, это -- херня.

Reply to
Kirill Frolov

Здравствуйте, Уважаемый Kirill!

Wed Jul 05 2006 21:36, Kirill Frolov wrote to Olga Nonova:

KF> Это не C++, это -- херня.

Херня, оно может быть и херня. Hо, ведь прекрасно работает! Очень быстро и с фиксированным временем на любое ветвление. Что кроет любые Ваши обсирания вокруг да около.

Всего Вам Хорошего Ольга

Reply to
Olga Nonova

Здравствуйте, Уважаемый Ruslan!

Wed Jul 05 2006 08:20, Ruslan Mohniuc wrote to Olga Nonova:

RM> Комментарии, надеюсь, не нужны?

В данном случае не нужны. Попробуйте теперь: case 'A':.... case 'ы':.... case '1':.... case 'Ж':....

Коментарии нужны?

Всего Вам Хорошего Ольга

Reply to
Olga Nonova
Reply to
Alexandr Torres

Здравствуйте, Уважаемый Alexandr!

Thu Jul 06 2006 01:57, Alexandr Torres wrote to Olga Nonova:

ON>> case 'A':.... ON>> case 'ы':.... ON>> case '1':.... ON>> case 'Ж':....

ON>> Коментарии нужны?

AT> Да. коммунтарии нужны.

Извольте. Кто программировал ПЛИСы знают, что состояния State_Machine часто задают принудительно в виде управляющих кодовых последовательностей. Эти последовательности выбирают как удобно, не обязательно в виде целых чисел, бегущей "1" или кода Грея. Для ваших любимых ПИКов- это может быть значение в регистре порта вывода, на котором хочется получить желаемую лично Вам последовательность кодов. Таким образом, выражением при switch будет именно этот порт, и вполне может оказаться необходимым распознавать на нем значения из моего примера: 'A','ы','1','Ж'.

Всего Вам Хорошего Ольга

PS. ДHК не беспокоит?

Reply to
Olga Nonova
Reply to
Alexandr Torres

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.