В vxworks каждая задача должна быть порождена с опцией VX_FP_TASK?

В vxworks каждая задача должна быть порождена с опцией VX_FP_TASK?

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

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

5
задан aks 12 February 2010 в 08:35
поделиться

2 ответа

VX_FP_TASK заставляет переключение контекста задачи включать регистры FP. Это увеличивает время переключения контекста. Если во время вашего приложения сроки и целевые показатели производительности могут быть выполнены даже с этими накладными расходами, то я предлагаю небольшую проблему в том, чтобы сделать это. Отсутствие VX_FP_TASK можно рассматривать как оптимизацию , которую следует применять с осторожностью, только если и когда это необходимо. Так что, если по умолчанию используется VX_FP_TASK, вам, вероятно, придется меньше проверять в тех немногих случаях, когда вам может потребоваться оптимизировать производительность; поскольку зачастую оптимизация не требуется для достижения требуемых результатов. Если накладные расходы, связанные с переключением контекста, создают или разрушают ваш проект, они в любом случае могут быть незначительными.

С другой стороны, хотя во встроенных системах FPU становятся все более распространенными, разработчики встроенных систем также часто используют FP как исключение, а не правило из-за традиционного отсутствия аппаратной поддержки FP. Поэтому одним из решений является наличие внутреннего правила проектирования, согласно которому плавающая точка не должна использоваться без формального обоснования и согласования: т.е. использование плавающей точки должно быть в дизайне, а не в решении программиста. Проверка обычно представляет собой простой случай сканирования источника для float , double и math.h .(поскольку, вероятно, сложно использовать числа с плавающей запятой, если ни то, ни другое не встречается в коде). Вы можете, например, добавить проверку статического анализа перед сборкой, которая ищет их и помечает предупреждение.

Во многих приложениях можно спроектировать так, чтобы математические операции FP были естественным образом ограничены конкретными задачами. Однако проблема возникает, когда кто-то решает использовать существующую функцию, предназначенную для использования в одной из этих задач, в другой, которая не является безопасной для FP. Это может быть трудно заметить; решение этой проблемы - иметь функции, использующие числа с плавающей запятой и которые могут использоваться в других задачах, для включения отладочного ASSERT, который проверяет параметры задачи с помощью taskOptionsGet ().

Таким образом, комбинация сканирования для использования float , double и math.h и добавление проверки ASSERT к функциям, которые их используют, будут вероятно защитит вас от внесения ошибок в сопровождение кода.

[добавлено 2010Feb14]

Поскольку сложные макросы, как правило, плохо, я полагаю, что следующие могут быть полезны (как упоминалось выше ):

#if NDEBUG
    #define ASSERT_FP_SAFE() ((void) 0)
#else
    #define ASSERT_FP_SAFE() do{ int opt; \
                                 STATUS st = taskGetOptions( taskIdSelf(), &opt ); \
                                 assert( st == OK && (opt & VX_FP_TASK) != 0 ) ; \
                               }while(0) ;
#endif

Этот макрос должен быть вставлен в любую функцию, которая использует float или double, или которая включает или любую другую зависимую от FP библиотеку, которую вы можете использовать (чего вы можете достичь с помощью текстового поиска). Утверждение тогда потерпит неудачу, если такая функция вызывается из не-FP-задачи.

Обратите внимание, что при проверке возврата от taskGetOptions () будет обнаружено использование плавающей запятой в контекстах прерывания. Хотя, если утверждение происходит в прерывании, вы можете не получить никакого вывода.Возможно, вызов logMsg () будет более безопасным; вы можете использовать это, если st! = OK, и assert () в противном случае.

К сожалению, это утверждение времени выполнения, поэтому для его проверки необходимо запустить код. Было бы лучше, если бы это можно было обнаружить с помощью статического анализа, но я не могу придумать простого метода. Однако, если вы также используете анализ покрытия кода, этого может быть достаточно. Это может быть хорошей привычкой, даже если вы решите сделать все задачи VX_FP_TASK; таким образом, если кто-то забудет сделать одно или другое, у вас есть шанс поймать это.

6
ответ дан 13 December 2019 в 19:26
поделиться

По опыту могу дать простой ответ: Всегда порождайте задачу с VX_FP_TASK. Особенно если ваш код может быть использован для разных архитектур.

В зависимости от компилятора (gnu, diab), флагов компиляции, которые вы используете, и архитектуры, регистры плавающей точки могут использоваться не только для операций с плавающей точкой. В большинстве архитектур регистры FP больше, чем обычные регистры, поэтому они становятся идеальными кандидатами для оптимизации кода.

Например, в процессорах PPC603, если вы используете C++ вместо обычного C, регистры FP будут использоваться для оптимизации, и если вы не включили VX_FP_TASK для этой задачи, она может испортить регистры FP другой задачи, даже если она не производит никаких вычислений!

Правильное выполнение важнее, чем производительность, и в большинстве случаев выигрыш в производительности не оправдывает риск, возникающий из-за его отсутствия.

Если вы хотите убедиться, что флаг включен во всех задачах, подумайте о добавлении хука, который всегда включает флаг во время создания задачи с помощью функции taskCreateHookAdd( )

3
ответ дан 13 December 2019 в 19:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: