QNX.ORG.RU

Разработка => Программирование под QNX => Тема начата: Krisya от Ноября 23, 2006, 02:38:20 pm



Название: время контекстного переключения
Отправлено: Krisya от Ноября 23, 2006, 02:38:20 pm
Подскажите пожалуйста, как измерить время контекстного переключения м/у нитями в одном процессе?


Название: время контекстного переключения
Отправлено: lestat от Ноября 23, 2006, 03:02:17 pm
Запустить два высокоприоритетных потока, в каждом заполнять большой массив (~32-64Mb) unsigned long'ов младшими тридцатидвумя битамовыми значениями полученными с помощью комманды процессора RDTSC. После заполнения всего массива - оба сбрасывать в файлы и в дальнейшем анализировать разрывы полученных значений:
Например:

thread 1
40
50
60
70
1200
1215
1225

thread 2
120
130
140
150
2400
2415
2425

Краткое объяснение: из потока 1 после чтения из RDTSC значения 70, произошло переключение контекста и в поток 2 оно попало в районе 120-го такта, значит ~50 тактов на переключение из потока 1 в поток 2. Приведенные цифры - для примера, в реалии там будут десятки и сотни тысяч тактов. Анализируем все дельты всех разрывов и вычисляем среднюю температуру по палате - это и есть время переключения контекста в тактах процессора. Естественно во время работы будут переключения контекста не только между двумя потоками, а и в другие процессы и потоки, но из-за высоких приоритетов наших потоков - этим можно пренебречь, остаются аппаратные прерывания - но от них никуда не деться, это наоборот хорошо, так как мы получим не теоретическое значение времени переключения контекста, а именно реальное, на которое мы можем в будущем рассчитывать.


Название: время контекстного переключения
Отправлено: olej от Ноября 26, 2006, 02:23:29 am
Krisya

Подскажите пожалуйста, как измерить время контекстного переключения м/у нитями в одном процессе?



unsigned long N = 1000;

// потоковая функция:
void* threadfunc ( void* data ) {
   uint64_t t = ClockCycles();
   for( unsigned long i = 0; i < N; i++ ) sched_yield();
   t = ClockCycles() - t;
   // дать спокойно завершиться 2-му потоку
   // до начала вывода
   delay( 100 );
   cout << pthread_self() << "   : cycles - " << t
        << "; on sched - " << ( t / N ) / 2 << endl;
   return NULL;
};

int main( int argc, char *argv[] ) {
   int opt, val;
   while ( ( opt = getopt( argc, argv, "n:" ) ) != -1 ) {
      switch( opt ) {
         // переопределения числа переключений
         case 'n' :
            if( sscanf( optarg, "%i", &val ) != 1 )
               cout << "parse command line error" << endl,
               exit( EXIT_FAILURE );
            if( val > 0 ) N = val;
            break;
         default :
            exit( EXIT_FAILURE );
       }
   };
   const int T = 2;
   pthread_t tid[ T ];
   // создать взаимодействующие потоки
   for( int i = 0; i < T; i++ )
      if( pthread_create( tid + i, NULL,
          threadfunc, NULL ) != EOK )
         cout << "thread create error",
         exit( EXIT_FAILURE );
   // и дожидаться их завершения . . .
   for( int i = 0; i < T; i++ )
      pthread_join( tid[ i ], NULL );
   exit( EXIT_SUCCESS );
};


И результаты:

# nice -n-19 p5t -n100
2       : cycles - 79490; on sched - 397
3       : cycles - 78350; on sched - 391
# nice -n-19 p5t -n1000
2       : cycles - 753269; on sched - 376
3       : cycles - 752069; on sched - 376
# nice -n-19 p5t -n10000
2       : cycles - 7494255; on sched - 374
3       : cycles - 7493225; on sched - 374
# nice -n-19 p5t -n100000
2       : cycles - 74897795; on sched - 374
3       : cycles - 74895800; on sched - 374
# nice -n-19 p5t -n1000000
2       : cycles - 748850811; on sched - 374
3       : cycles - 748850432; on sched - 374

- как видите они отличаются достаточно высокой устойчивостью.

P.S. ... а, в принципе, время переключения контекста как между поток-поток (в пределах 1-го процесса), так и между процесс-процесс - практически равны между собой (как, возможно, это и не покажется вам странным ); и именно в QNX это сделано "по-чесному" и занимает очень малое время.


Название: время контекстного переключения
Отправлено: bioalecs от Ноября 30, 2006, 02:27:34 pm
Olej
[/quote]
в принципе, время переключения контекста как между поток-поток (в пределах 1-го процесса), так и между процесс-процесс - практически равны между собой (как, возможно, это и не покажется вам странным );
Цитата: Olej


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


Название: время контекстного переключения
Отправлено: olej от Ноября 30, 2006, 06:52:50 pm
bioalecs

У меня при прогоне данной проги и проги для полученеия времени переключения между двумя процессами времена отличаются где-то в 1,5 - 2 раза, что мне кажется вполне приемлимо, т.к. у потоков совпадает часть адресного пространства и при их переключении нет необходимости перегружать весь контекст процесса(как в случае с процессами)....


Так примерно и есть .
Но, заметьте, что на 1-но решедулирование у вас приходтся 4 системных тика, на которых выполняется достаточно много работы по обслуживанию системного времени (и 1 из них всегда совмещён с переключением) - из-за того, что это время соизмеримо (больше?) времени переключения контекста, оно "съедает" разницу в переключении потока или процесса. Как я это понимаю.


Название: время контекстного переключения
Отправлено: bioalecs от Декабря 03, 2006, 08:39:56 pm
Olej
оно "съедает" разницу в переключении потока или процесса. Как я это понимаю

Не знаю, но даже производители qnx(QSS) различают время переключения процессов и потоков ( они у них тоже в 2 раза различаются )... Если не верите зайдите на сайт www.qnx.com и там поищите в поиске benchmarks.

PS: Для P4 1.8 с 4 Gb и QNX 6.3.0 SP2 следующие данные:
    inter-thread: 0.636 microsec
    inter-process: 1.174 microsec