Страниц: [1]
  Печать  
Автор Тема: время контекстного переключения  (Прочитано 6276 раз)
Krisya
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля
« : Ноября 23, 2006, 02:38:20 pm »

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

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #1 : Ноября 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
QOR.Team
****
Offline Offline

Сообщений: 42



Просмотр профиля
« Ответ #2 : Ноября 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
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля
« Ответ #3 : Ноября 30, 2006, 02:27:34 pm »

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


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

Сообщений: 42



Просмотр профиля
« Ответ #4 : Ноября 30, 2006, 06:52:50 pm »

bioalecs

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


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

Сообщений: 0


Просмотр профиля
« Ответ #5 : Декабря 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
Записан
Страниц: [1]
  Печать  
 
Перейти в: