crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Непонятное срабатывание rdtsc() в Linux ( Ubuntu 10.10 )
Белый пони
  опции профиля:
сообщение 17.3.2011, 16:51
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 27.1.2011
Пользователь №: 2373

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте!

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

dumb3.cpp
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdint.h>

extern __inline__ uint64_t rdtsc();

void SetSIO( int fd,
                  unsigned int BaudRate,   // B0 B50 ... B9600 B19200 B38400
                  unsigned int Parity,     // 1 ... 4 ( odd, even, mark, space)
                  unsigned int DataBits,     // CS5 ... CS8
                  unsigned int StopBits,     // 0 или 1 (1 или 2)
                  unsigned int FlowControl); // 0 .. 3 ( RTS/CTS,  XON/XOFF, both, none)

int main(void)
{
unsigned char R[50];  // read data
char key[1];

short bytesrd;
int fp;              // tty's descriptor

unsigned long ini, end;   // rdtsc() limits


///////// keyboard settings, reserve copy of initial/////
struct termios tp1;
struct termios tp2;

  tcgetattr(0,&tp1);
  tp2=tp1;
  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tcsetattr(0,TCSANOW,&tp2);
////////////////////////////////////////////////////////

fp = open( "/dev/ttyS0", O_RDWR | O_NONBLOCK);
SetSIO( fp, B9600, 0, CS8, 0, 3);

fd_set set0, set;      // forming set of COM and keyboard descriptors
FD_ZERO( &set);
FD_SET( fp, &set);
FD_SET(  0, &set);
set0 = set;

ini = rdtsc();
while(1)
    {
    if ( select( fp+1, &set, NULL, NULL, NULL ) > 0)
        {
        if( FD_ISSET( fp, &set))
            {
            bytesrd = read( fp, R, 1);            
                        if( bytesrd == -1){ printf("\ninit oi!!!"); break;}            
            end = rdtsc();
            printf("%2X %li \n", R[0], (end - ini)/3000 ); // примерная частота процессора в МГц
            ini = end;
            }

        if( FD_ISSET( 0, &set) )    
            {
            bytesrd = read( 0, key, 1);
            if ( bytesrd != -1 )printf(" %c pressed. \n", key[0]);
            if( key[0] == 27){ break;}
            }
        }
    
    set = set0;    
    }
tcflush( fp, TCIOFLUSH);
tcsetattr(0,TCSANOW,&tp1);   // restore keyboard settings

close(fp);
printf("\n");
}


extern __inline__ uint64_t rdtsc() {
   uint64_t x;
   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
   return x;
}
(процедура SetSIO - настраивает параметры com-порта, она громоздкая и мне кажется, к проблеме отношения не имеет. Но если что - могу и её запостить)

Cигналы принимаются от девайса с известными интервалами - 10 раз в секунду пачками по 9 байт. перед первый байтом пачки - большая пауза, примерно 95 мс.
Проблема в том, что эта самая программа, будучи запущения разными способами, выдаёт разные временные промежутки:

При запуск в терминале графической оболочки Gnome ("./dump3") в терминал выводится:
1
//пришедший байт, временной интервал после предыдущего байта в микросекундах
2 96434
4 22
F4 8
0 8
30 7
13 7
4 7
EF 7
0 3935
2 96471
4 23
F4 8
0 8
30 7
13 7
4 7
EF 7
0 3971
2 96436
4 22
F4 8
0 8
30 8
13 7
4 7
EF 7
0 3968
...

При запуске в терминале без графической оболочки (Cntrl+Alt+F1 в Убунту) в терминал выводится:
2
2 96464
4 231
D0 240
0 239
30 227
13 227
4 227
CB 225
0 2398
2 96461
4 233
D2 238
0 238
30 225
13 225
4 224
CD 224
0 2406
...


При запуске в том же терминале без графической оболочки с направлением вывода не в консоль, а в файл ( "./dump3.cpp > yyy.txt"):
3
2 29861
4 49
54 5
0 4
30 4
13 4
4 4
50 4
0 3934
2 96454
4 5
54 4
0 4
30 4
13 4
4 4
50 4
0 3986
2 96463
4 5
54 4
0 4
30 4
13 4
4 4
50 4
0 3986

Откуда такие различия?
И где значения ближе к правде?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Iron Bug
  опции профиля:
сообщение 20.3.2011, 20:05
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


сколько процессоров на машине? на многопроцессорных (многоядерных) процах эту функцию использовать нельзя. используй clock_gettime с CLOCK_MONOTONIC.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.12.2024, 13:08