Могу ли я иметь 1 процессорное ядро ​​только для моей программы?


12

Мне нужно рассчитать разницу во времени между высоким -> низким и низким -> высоким фронтом сигнала на выводах GPIO. Я написал простую программу, которая делает это. После того, как я пробежался некоторое время, я был вполне доволен результатом (вариации 0,01 с). Но время от времени возникала ошибка 0,5 с. Я думал, что это может быть связано с каким-то другим системным процессом, запущенным в то время. Итак, мой вопрос:

Могу ли я зарезервировать одно процессорное ядро ​​только для моей программы и разрешить другие 3 ядра для системы?

Я использую Raspbian Jessie Lite, поэтому думаю, что для его запуска будет достаточно 3 ядер.


4
Я предполагаю, что вы опрашиваете в цикле состояние вывода GPIO. Это очень восприимчиво к тому, как операционная система решит выполнить вашу программу, которая будет проводить большую часть своего времени, занимая центральный процессор, не делая при этом ничего полезного. Возможно, вы захотите найти способ установки прерывания для определенного вывода GPIO, который вы можете использовать, чтобы ваша программа спала между фронтами сигнала на выводах GPIO.
Флориан Кастеллан

4
Не знаю, какой у вас проект, но иногда лучше подходит микроконтроллер, особенно когда вам нужно больше системы, похожей на реальную. Arduino предлагает множество вариантов, и вы можете написать свою программу на C / C ++.
SnakeDoc

@Florian В RPi.GPIO есть функция, похожая на прерывание. Он будет блокировать программу до тех пор, пока не будет обнаружен край (источник: sourceforge.net/p/raspberry-gpio-python/wiki/Inputs ).
NonStandardModel

@ SnakeDoc Я знаю, что микроконтроллер лучше. Я надеялся избежать этого, потому что мне не нужна микросекундная точность. 1/100 секунды более чем достаточно. Также мне нужен только разность времени, поэтому, если есть задержка, я надеялся, что она будет одинаковой для старта и остановки. Если это не работает, я должен пойти с микроконтроллером, подключенным к RPi, для хранения данных.
NonStandardModel

1
Или получите ОС реального времени, работающую на PI. Проблема с вашей настройкой, это зависит от "наилучшего усилия" со стороны ОС. В зависимости от того, что еще происходит в то время, когда ваша программа запрашивает привилегированный доступ к GPIO, она может оказаться в очереди за другими задачами, которые ОС выполняет в данный момент. Ваша пользовательская программа получит более низкий приоритет, чем системные задачи. Также есть вытеснение, которое означает, что во время выполнения вашей программы она может быть «приостановлена ​​и« отложена »ОС для запуска другого процесса, а это означает, что ваши временные наблюдения могут быть искажены»
SnakeDoc

Ответы:


13

Выделение ядра, вероятно, излишне.

Я предлагаю вам попробовать мою библиотеку pigpio . По умолчанию время GPIO изменяется в пределах 10 мкс.

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

pigpio не устанавливается по умолчанию в Jessie Lite. Либо установите последнюю версию со ссылочного сайта, либо установите более старую версию в репозитории.

sudo apt-get install pigpio python-pigpio python3-pigpio

pigpio - Library for Raspberry Pi GPIO control
python-pigpio - Python module which talks to the pigpio daemon (Python 2)
python3-pigpio - Python module which talks to the pigpio daemon (Python 3)

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

4

Вы можете привязать свою программу к одному ядру, используя, schedutilsкак описано в этой статье о Cyberciti :

sudo apt-get install schedutils
sudo taskset -c 3 -p 13545  # Lock PID 13545 to core 3

Другие процессы все еще могут быть запланированы на том же ядре, хотя. Итак, второе, что нужно сделать, это убедиться, что ваша команда выполняется с наивысшим приоритетом, используя команду nice (это скажет ядру Linux, что другие процессы должны быть прерваны при необходимости). Запустите вашу программу следующим образом:

nice -n -20 your-program

Есть и другие возможные причины проблем с синхронизацией. Это не так просто сделать:

  • Если вы программируете на Python, существует сборщик мусора, который иногда останавливает вашу программу, чтобы освободить неиспользуемую память.
  • Прерывания заставляют процессор обрабатывать что-то еще, чем вы хотите. Например, сетевые пакеты или другой ввод / вывод.
  • Если ваша программа много спит, возможно, существуют другие процессы, которые заполняют кэш процессора (кэш L1 / L2). Это заставляет вас ждать доступа к ОЗУ.
    • Еще хуже, если ваша RAM заполнена, так что ваш процесс выгружается на диск, потому что SD-карты работают медленно.

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


2
Вместо того, чтобы хорошо, было бы лучше дать процессу приоритет в реальном времени, который обеспечил бы его предпочтение процессам не в реальном времени.
Joan

Хороший вопрос, я добавлю в записке об этом.
Эмиль

1
"gc.disable ()" что произойдет, если вы отключите сборщик мусора?
Кейн,

@ Кейн Вы можете получить утечку памяти. Скажем, у вас есть объект A, у которого есть переменная, которая указывает на B. Python будет отслеживать эту ссылку как число, он знает, что у B есть 1 объект, указывающий на него. Удалите А, когда вам это больше не нужно. Счетчик ссылок для B будет уменьшаться, и если он достигнет 0, Python тоже сможет освободить B. Это называется подсчетом ссылок. Но теперь скажем, что B имеет ссылку обратно на A. Теперь у вас есть кластер объектов, указывающих друг на друга. Никто из них не достигнет 0 и не будет освобожден. GC может найти такие кластеры и удалить их, когда основная программа не указывает «в» кластер.
Эмиль

1
Я добавлю предложения, которые вы внесли в мой проект. Но я надеюсь избежать слишком сложных тем. В этом случае я полагаю, что лучше сделать обнаружение прерывания микроконтроллера и подключить его к RPi только для сохранения данных. Спасибо!
NonStandardModel

2

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

Вместо этого вы должны использовать микроконтроллер для измерения этого времени, желательно с использованием прерываний, и передать информацию Пи позже.


1
Разве нельзя получить прерывания на выводах GPIO на Raspberry Pi?
Флориан Кастеллан

Конечно, это зависит от того, есть ли какая-то другая часть требований к дизайну, которая делает Linux-машину более подходящей, чем MCU. RPi прекрасно справляется с этой задачей, как и MCU с тактовой частотой 10 МГц.
Шон

1

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

Насколько я знаю ОС (ОС общего назначения), которую мы используем, не предназначены для использования в системах реального времени, поэтому, если вы хотите запустить свой процесс в режиме реального времени, чтобы никакой другой процесс не мешал ему, вам нужно идти для ОС реального времени (ОСРВ). Может быть, они придумают основной выбор. :)


1
Есть ли хорошие бесплатные ОСРВ?
Кейн,

RTLinux и Vxworks являются примерами RTOS, и они также хороши. Но перед установкой вам нужно изучить ОС (то, что было целью ее создания), чтобы она могла удовлетворить ваши потребности.
Вишваджит Вишу
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.