LINUX.ORG.RU

Должны ли быть видны в inline-функции в профиляторе Gprof ?


0

1

Вопрос в следующем.

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

Такие функции, да еще и вызываемые в циклах, имеет смысл объявлять инлайновыми. Это необходимо, чтобы не тратилось время на работу со стеком/регистрами при подготовке вызова, на сам вызов функции, на возврат результата.

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

При профилировании через gprof я вижу, что эти inline функции показываются в gprof, и gprof показывает число их вызовов.

Вопрос:

Это gprof такой умный, видит работу инлайновых функций, подсчитывает число их «виртуальных» вызов? Или данные функции, несмотря на директиву inline, скомпилены таки в виде обычных функций, и поэтому их видит gprof?

Пример функций:

inline unsigned char RC5Simple::RC5_GetByteFromWord(RC5_TWORD w, int n)
{
 unsigned char b=0;

 switch (n) {                                                                                  
   case 0:
       b=(w & 0x000000FF);
       break; 
   case 1:
       b=(w & 0x0000FF00) >> 8;
       break; 
   case 2:
       b=(w & 0x00FF0000) >> 16;
       break; 
   case 3:
       b=(w & 0xFF000000) >> 24;
 }

 // RC5_LOG(( "GetByteFromWord(%.8X, %d)=%.2X\n", w, n, b ));

 return b;
}    


inline RC5_TWORD RC5Simple::RC5_GetWordFromByte(unsigned char b0,
                                                unsigned char b1, 
                                                unsigned char b2, 
                                                unsigned char b3)
{
 return b0+
        (b1 << 8)+
        (b2 << 16)+
        (b3 << 24);
}

А вот как они выглядят в профилировщике:

  0.00      0.73     0.00  4289320     0.00     0.00  RC5Simple::RC5_GetByteFromWord(unsigned long, int)
  0.00      0.73     0.00  1072330     0.00     0.00  RC5Simple::RC5_GetWordFromByte(unsigned char, unsigned char, unsigned char, unsigned char)
...
                0.00    0.00 4289320/4289320     RC5Simple::RC5_GetByteFromWord(unsigned long, int) [423]
                0.00    0.00 1072330/1072330     RC5Simple::RC5_GetWordFromByte(unsigned char, unsigned char, unsigned char, unsigned char) [424]
★★★★★

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

io ★★ ()

union не стильно?

anonymous ()

а ты глянь asm который строит gcc для gprof - всё встанет на свои места.

ps. кстате

// можно так
#define RC5_GetByteFromWord(w,n) [n](unsigned char *)&(w)
// и во многих случая даже
RC5_TWORD RC5_GetWordFromByte(unsigned char b0,unsigned char b1,unsigned char b2,unsigned char b3) {
   return *(RC5_TWORD *)&b0;
}

MKuznetsov ★★★★★ ()

inline unsigned char RC5Simple::RC5_GetByteFromWord(RC5_TWORD w, int n)

Можно переписать без условий.

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

Ты уверен, что b1, b2, b3 будут вот так ровнёхонько стоять в памяти аккурат рядом с b0? А если архитектура big-endian окажется?

Я сделал обе функции через дефайны, убрал ветвления:

#define RC5_GET_BYTE_FROM_WORD(w, n) ((unsigned char)((w) >> ((n)*8) & 0xff))
#define RC5_GET_WORD_FROM_BYTE(b0, b1, b2, b3) ((RC5_TWORD)(b0 + (b1 << 8) + (b2 << 16)+ (b3 << 24)))
Xintrea ★★★★★ ()
Ответ на: комментарий от MKuznetsov

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

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

да, ничего, комментарий бесполезен

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