workproc((int)data);

 trtime[id].f = ClockCycles();

 pthread_barrier_wait(&bfinish);

 return NULL;

}

int main(int argc, char *argv[]) {

 // здесь только обработка многочисленных ключей...

 int opt, val, nthr = 1, nall = SHRT_MAX;

 while ((opt = getopt(argc, argv, 't:n:p:a:')) != -1) {

  switch(opt) {

  case 't':

   if (sscanf(optarg, '%i', &val) != 1)

    perror('parse command line failed'), exit(EXIT_FAILURE);

   if (val > 0 && val <= SHRT_MAX) nthr = val;

   break;

  case 'p':

   if (sscanf(optarg, '%i', &val) != 1)

    perror('parse command line failed'), exit(EXIT_FAILURE);

   if (val != getprio(0))

    if (setprio(0, val) == -1)

     perror('priority isn't a valid'), exit(EXIT_FAILURE);

   break;

  case 'n':

   if (sscanf(optarg, '%i', &val) != 1)

    perror('parse command line failed'), exit(EXIT_FAILURE);

   if (val > 0) nsingl *= val;

   break;

  case 'a':

   if (sscanf(optarg, '%i', &val) != 1)

    perror('parse command line failed'), exit(EXIT_FAILURE);

   if (val > 0) nall = val;

   break;

  default:

   exit(EXIT_FAILURE);

  }

 }

 // ... вот здесь начинается собственно сама программа.

 if (nthr > 1)

  cout << 'Multi-thread evaluation, thread number = ' << nthr;

 else cout << 'Single-thread evaluation';

 cout << ' , priority level: ' << getprio(0) << endl;

 __clockperiod clcout;

 ClockPeriod(CLOCK_REALTIME, NULL, &clcout, 0);

 // интервал диспетчеризации - 4 периода tickslice

 // (системного тика):

 cout << 'rescheduling = '

  << clcout.nsec * 4 / 1000000. << endl;

 // калибровка времени выполнения в одном потоке

 const int NCALIBR = 512;

 uint64_t tmin = 0, tmax = 0;

 tmin = ClockCycles();

 workproc(NCALIBR);

 tmax = ClockCycles();

 cout << 'calculating = '

  << cycle2milisec(tmax - tmin) / NCALIBR << endl;

 // а теперь контроль времени многих потоков

 if (pthread_barrier_init(&bstart, NULL, nthr) != EOK)

  perror('barrier init'), exit(EXIT_FAILURE);

 if (pthread_barrier_init(&bfinish, NULL, nthr + 1) != EOK)

  perror('barrier init'), exit(EXIT_FAILURE);

 trtime = new interv[nthr];

 int cur = 0, prev = 0;

 for (int i = 0; i < nthr; i++) {

  // границы участков работы для каждого потока.

  cur = (int)floor((double)nall / (double)nthr * (i + 1) + .5);

  prev = (int)floor((double)nall / (double)nthr * i + 5);

  if (pthread_create(NULL, NULL, threadfunc, (void*)(cur - prev)) != EOK)

   perror('thread create'), exit(EXIT_FAILURE);

 }

 pthread_barrier_wait(&bfinish);

 for (int i=0; i < nthr; i++ ) {

  tmin = (i == 0) ? trtime[0].s : __min(tmin, trtime[i].s);

  tmax = ( i == 0 ) ? trtime[0].f : __max(tmax, trtime[i].f);

 }

 cout << 'evaluation = '

  << cycle2milisec(tmax - tmin) / nall << endl;

 pthread_barrier_destroy(&bstart);

 pthread_barrier_destroy(&bfinish);

 delete trtime;

 exit(EXIT_SUCCESS);

}

Логика этого приложения крайне проста:

• Есть некоторая продолжительная по времени рабочая функция (workproc), выполняющая массированные вычисления.

• Многократно (это число определяется ключом запуска а) выполняется рабочая функция. Хорошо (то есть корректнее), если время ее единичного выполнения, которое задается ключом n, больше интервала диспетчеризации системы (в системе установлена диспетчеризация по умолчанию - круговая, или карусельная).

• Весь объем этой работы делится поровну (или почти поровну) между несколькими (ключ t) потоками.

• Сравниваем усредненное время единичного выполнения рабочей функции для разного числа выполняющих потоков (в выводе 'calculating' — это время эталонного вычисления в одном главном потоке, a 'evaluation' — время того же вычисления, но во многих потоках).

• Для того чтобы иметь еще большую гибкость, предоставляется возможность переопределять приоритет, под которым в системе все это происходит (ключ p).

Вот самая краткая сводка результатов (1-я строка вывода переносится для удобства чтения):

# t1 -n1 -t1000 -a2000

Multi-thread evaluation, thread number = 1000, priority level: 10

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату