QNX/UNIX: Анатомия параллелизма
QNX/UNIX: Анатомия параллелизма читать книгу онлайн
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.
В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
ClockPeriod(CLOCK_REALTIME, NULL, &clcold, 0);
if (argc > 2 && atoi(argv[2]) > 0) {
_clockperiod clcnew = { atoi(argv[2]) * 1000, 0 };
ClockPeriod(CLOCK_REALTIME, &clcnew, &clcold, 0);
}
timespec interval;
sched_rr_get_interval(0, &interval);
cout << "Rescheduling interval = "
<< (double)interval.tv_nsec / 1000000 << " msec. " << endl;
uint64_t t = ClockCycles();
for (int i = 0; i < numpar; i++)
pthread_create(&tids[i], NULL, threadfunc, NULL);
for (int i = 0; i < numpar; i++)
pthread_join(tids[i], NULL);
t = ClockCycles() - t;
cout << "Threads scheduling time " << cycle2milisec(t)
<< " msec. [" << t << " cycles]" << endl;
ClockPeriod(CLOCK_REALTIME, &clcold, NULL, 0);
exit(EXIT_SUCCESS);
}
Наконец, для сравнительного анализа выполним тот же объем вычислительной работы в одиночном потоке, то есть в последовательной «классической» программе ( файл p4-3.cc):
i
nt main(int argc, char *argv[]) {
int numpar = 1;
if (argc > 1 && atoi(argv[1]) > 0)
numpar = atoi(argv[1]);
_clockperiod clcold;
ClockPeriod(CLOCK_REALTIME, NULL, &clcold, 0);
if (argc > 2 && atoi(argv[2]) > 0) {
_clockperiod clcnew = { atoi(argv[2]) * 1000, 0 };
ClockPeriod(CLOCK_REALTIME, &clcnew, &clcold, 0);
}
timespec interval;
sched_rr_get_interval(0, &interval);
cout << "Rescheduling interval = "
<< (double)interval.tv_nsec / 1000000. << " msec." << endl;
uint64_t t = ClockCycles();
workproc(1000 * numpar);
t = ClockCycles() - t;
cout << "Single scheduling time. " << cycle2milisec(t)
<< " msec. [" << t << " cycles]" << endl;
ClockPeriod(CLOCK_REALTIME, &clcold, NULL, 0);
exit(EXIT_SUCCESS);
}
Выполняем 3 полученных теста для различных значений периода системного тика (показано группами по 3 запуска) в таком порядке: одиночный процесс, параллельные потоки, параллельные процессы:
# nice -n-19 p4-3 10
Rescheduling interval = 3.99939 msec
Single scheduling time: 5928.8 msec [3169850746 cycles]
# nice -n-19 p4-2 10
Rescheduling interval = 3.99939 msec.
Threads scheduling time: 5919.82 msec. [3165049513 cycles]
# nice -n-19 p4-1 10
Rescheduling interval = 3.99939 msec.
Forks scheduling time: 5962.21 msec. [3187713371 cycles]
# nice -n-19 p4-3 10 50
Rescheduling interval = 0.197788 msec
Single scheduling time: 6427.33 msec. [3436394566 cycles]
# nice -n-19 p4-2 10 50
Rescheduling interval = 0.197788 msec.
Threads scheduling time: 6207.96 msec. [3319104030 cycles]
# nice -n-19 p4-1 10 50
Rescheduling interval = 0.197788 msec
Forks scheduling time 6029.23 msec. [3223548073 cycles]
# nice -n-19 p4-3 10 20
Rescheduling interval = 0.077104 msec.
Single scheduling time: 6745.37 msec. [3606433666 cycles]
# nice -n-19 p4-2 10 20
Rescheduling interval = 0.077104 msec
Threads scheduling time: 6762.69 msec [3615692975 cycles]
# nice -n-19 p4-1 10 20
Rescheduling interval = 0.077104 msec
Forks scheduling time: 6647.42 msec [3554062343 cycles]
# nice -n-19 p4-3 10 11
Rescheduling interval = 0.04358 msec
Single scheduling time. 7517.74 msec [4019381476 cycles]
# nice -n-19 p4-2 10 11
Rescheduling interval = 0.04358 msec
Threads scheduling time: 7638.89 msec. [4084155676 cycles]
# nice -n-19 p4-1 10 11
Rescheduling interval = 0.04358 msec.
Forks scheduling time: 7679 29 msec. [4105758575 cycles]
# nice -n-19 p4-3 10 10
Rescheduling interval = 0.036876 msec.