LINUX.ORG.RU

[gprof]Результаты удивляют(по крайней мере меня)


0

0

Мозг просто схлопнулся. Может, кто подскажет, на что эти симптомы указывают?

Есть программа, которая в одном потоке данные принимает и пишет в циклический буфер, а в другом потоке, соответственно, читает их из буфера. Работа с буфером посторенна по такой схеме:

Запись:
1) Буфер полон? если да, то подожать и проверить еще раз, если нет, то
2) Взять указатель, куда писать. Записать. Передвинуть указатель.

Чтение:
1) Буфер пуст? если да, то подожать и проверить еще раз, если нет, то
2) Взять указатель, откуда читать. Обработать. Передвинуть указатель

 25.84      2.32     0.77 569435332     0.00     0.00  RingBuffer<char, PThreadMutex>::isEmpty()
  7.05      2.87     0.21 18397292     0.01     0.01  RingBuffer<char, PThreadMutex>::isFull()
  2.35      2.94     0.07 26900264     0.00     0.00  RingBuffer<char, PThreadMutex>::getWritePtr()
  1.34      2.98     0.04     6343     6.31     6.31  RingBuffer<char, PThreadMutex>::moveWritePtr()
  0.00      2.98     0.00    14115     0.00     0.00  RingBuffer<char, PThreadMutex>::moveReadPtr()
  0.00      2.98     0.00     8427     0.00     0.00  RingBuffer<char, PThreadMutex>::getReadPtr()

Первые две строчки вполне предсказуемы, а вот откуда берется различное количество вызовов для getWritePtr/moveWritePtr и getReadPtr/moveReadPtr, я, откровенно говоря, не понимаю. И то, что чтений больше записей.

Лишних потоков точно не создается(для проверки воткнул лог в начало и конец потоковых функций).

Если кто-то думает, что накосячил в коде, то вот так реализовано чтение из кольцевого буфера и запись содержимого в файл:

if( !thread->stream_data->isEmpty() )
{
  buf = thread->stream_data->getReadPtr();
  write( outfd, buf, msg_len );
  thread->stream_data->moveReadPtr();
}

★★

OFFTOPIC

if( !thread->stream_data->isEmpty() ) 
{ 
  buf = thread->stream_data->getReadPtr(); 
  write( outfd, buf, msg_len ); 
  thread->stream_data->moveReadPtr(); 
}

То что ты накосячил в коде нет никаких сомнений.

pathfinder ★★★★
()
Ответ на: ONTOPIC от pathfinder

Ага, спасибо. Попробуем.

kulti ★★
() автор топика
Ответ на: комментарий от Reset

Ну, да. Меня количество вызовов и смущало. А чем еще можно отпрофилировать, чтобы multithread поддерживало? oprofile еще сгуглился, но его пока не смотрел...

kulti ★★
() автор топика

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

xtron
()
Ответ на: комментарий от xtron

С чего вы взяли, что не использую? Разделяемый ресурс - это кольцевой буфер, а он используется через thread-safety обертку.

kulti ★★
() автор топика
Ответ на: комментарий от kulti

>И где, разрешите поинтересоваться?

Отсутствие проверки возвращаемого значения от write() сильно режет глаза. Такие ошибки могут показаться ерундовыми, но это далеко не так.

pathfinder ★★★★
()
Ответ на: комментарий от kulti

>Неа, не помогло. Та же «ересь».

Я имел ввиду, что grpof плохо подходит для многонитевых приложений. Этим и объясняется такое странное поведение. А тот костыль в примере лучше не трогать.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Это понятно. write чисто в тестовых целях использовался.

kulti ★★
() автор топика
Ответ на: комментарий от pathfinder

Я уже понял =) спасибо за помощь

kulti ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.