2010-01-05 3 views
3

Я работаю над встроенным приложением C++, работающим на Linux. Недавно я столкнулся с некоторыми действительно странными проблемами производительности с pthreads.Производительность потока Linux очень быстро под GDB, но очень медленно, иначе

В моей системе имеется 8 потоков, передающих информацию взад и вперед, защищенную с помощью блокировки мьютекса pthread. При автономном выполнении моего приложения производительность потока крайне затруднительна при блокировке мьютекса. Блокировка и разблокировка мьютекса ~ 200 раз занимает 2,4 секунды на плате ARM на 500 МГц и дольше на моей плате 200 МГц.

Странно, что при запуске приложения под GDB приложение работает очень быстро. Тот же блок кода, который занимал 2,4 секунды автономно, занимает около 2 мс при запуске GDB.

Я тестировал это поведение на двух разных SBC на базе ARM: один работает под управлением Linux 2.4.26 с gcc 3.4.4 и glibc 2.3.2, а другой с Linux 2.6.21 также с gcc 3.4.4 и glibc 2.3.2.

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

ответ

3

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

И не забывайте, как правило, select isn't broken

вы используете LinuxThreads или NPTL («ядро» темы?) Если вы используете последний, вы можете также попытаться Трассирование приложения.

+0

Вы были правы, это было не сломано, конечно. :) Я сузил проблему до сторонней структуры, которую мы используем для функций конечного автомата. Он использовал стандартный мьютез pthread вместо рекурсивного. Изменение мьютекса на рекурсивное приводит к тому, что программа работает так же, как в GDB. Спасибо за ваш отзыв! – Maha

0

Вы уверены, что инициализируете мьютекс так, как считаете себя? Является ли эта вещь в переменном или выделенной области файла? Я думаю, что gdb заканчивается тем, что дает вам другой набор параметров на мьютексе из-за удачи в инициализации памяти.

+0

Спасибо за отзыв. Это глобальная переменная, инициализированная так: pthread_mutex_t pThreadMutex = PTHREAD_MUTEX_INITIALIZER; – Maha

+0

Urk. это должно быть безопасным в любом случае. Полагаю, вы можете попробовать явный init и убедиться, что вам нравятся параметры. – bmargulies

1

Идея, на которую вы могли бы обратить внимание, это значение счета спина. Это, безусловно, отличается от ARM вместо системы Intel.

Вы можете попробовать с помощью «pthread_mutex_trylock()», а затем сделать явное «sched_yield()», если он не сможет захватить блокировку, возможно, добавит миллисекундный сон внутри цикла. С помощью этого вы можете разбить операцию блокировки и посмотреть, есть ли какие-либо противоречия в блокировке.

Я бы поспорил, что вам нужно посмотреть исходный код или, по крайней мере, дизассемблированный «pthread_mutex_lock», чтобы исправить его.