В vxworks следует ли создавать каждую задачу с опцией VX_FP_TASK? - PullRequest
5 голосов
/ 12 февраля 2010

В vxworks следует ли создавать каждую задачу с опцией VX_FP_TASK?

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

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

Ответы [ 3 ]

6 голосов
/ 12 февраля 2010

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 к функциям, которые их используют, вероятно, защитят вас от ошибок при обслуживании кода.

[добавлено 2010 Фев14]

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

#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; таким образом, если кто-то забудет сделать одно или другое, у вас есть шанс его поймать.

3 голосов
/ 16 февраля 2010

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

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

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

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

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

2 голосов
/ 21 января 2012

ВСЕГДА используйте VX_FP_TASK! Стоимость его отсутствия и попыток отследить ошибочные ошибки, которые в результате невероятно дорогие.

...