Сорри, что не дождался ответа в личке.
Вот загрузка по ядрам и как видишь рендеринг съел 80% и так оно и есть.
Я не могу сказать, что именно рендеринг все 80% отъел. Ведь там могут быть и системные процессы, или даже некоторые из оставшихся потоков. К сожалению, на картинке этого не увидишь. Так же, как и того, что если именно рендеринг занял 80%, то остальные потоки вполне могут занимать не больше 20% (хотя судя по раскладке по потокам ниже на выложенном тобой скрине, там два примерно одинаковы по загрузке и два почти по нулям). К тому видно, что процессор не нагружен, одно ядро вообще ничем не занято. Чтобы понять на что способны потоки, надо дать на каждый полную нагрузку.
Поэтому я решил немного поэкспериментировать. Поставил твое приложение на виртуалку и выделил все четыре ядра, чтобы было по чему потоки раскидывать. Отсутствие нагрузки я решил добавлением бесконечного счетчика
в каждую функцию, выделяемую в поток (print_values, getValues и calcAccel) в файле myOBD.py . Если каждый поток питона может использовать весь остаток ядра, на котором он крутится, то мы должны получить три загруженных полностью ядра. Однако этого не произошло (см. картинку 1).
Общая загрузка по ядрам получилась ~153%.
Теперь убиваем приложение myOBD.py, чтобы оценить, сколько из нагрузки съедала система и другие открытые приложения. Общая нагрузка по ядрам упала до 68% (см. картинку 2).
Таким образом, приложение занимало порядка 90%, т.е. на все потоки, раскиданные по ядрам, суммарно тратилось не больше одного ядра.