QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович
int main(int argc, char *argv[]) {
uint64_t t = ClockCycles();
pthread_t tid;
pthread_create(&tid, NULL, threadfunc, NULL);
pthread_join(tid, NULL);
t = ClockCycles() - t;
cout << "Thread time, " << cycle2milisec(t) << " msec. [" << t <<
" cycles]" << endl;
exit(EXIT_SUCCESS);
}
На результаты этого теста (в отличие от предыдущего) уже достаточно существенно влияет приоритет, под которым выполняется задача, поэтому проделаем его с достаточно высоким приоритетом (29):
# nice -n-19 p2-2
Thread time: 0.147139 msec. [78667 cycles]
# nice -n-19 p2-1
Fork time: 2.5366 msec. [1356179 cycles]
Вот так… время порождения нового «пустого» процесса, даже минимального размера (размер исполняемого файла этого процесса чуть больше 4 Кбайт), почти в 20 раз больше затрат на создание потока! А для процессов большого объема эта разница может доходить до 3–4 порядков (см. результаты первого теста).
Далее рассмотрим сравнительную эффективность с другой стороны: будет ли диспетчеризация многочисленных потоков, принадлежащих одному процессу, эффективнее диспетчеризации такого же количества отдельных процессов? Для процессов задача текстуально выглядит так ( файл p4-1.cc):
void workproc(int how = 1) {
const int nsingl = 1000, msingl = 30;
for (int j = 0; j < how; j++) // ... имитация вычислений
for (uint64_t i = 0; i < msingl; i++)
for (uint64_t k = 0; k < nsingl; k++)
k = (k + 1) - 1;
}
int 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();
for (int i = 0, i < numpar; i++) {
pid_t pid = fork();
if (pid == -1) perror("fork"), exit(EXIT_FAILURE);
if (pid == 0) {
workproc(1000);
exit(EXIT_SUCCESS);
}
}
for (int i = 0; i < numpar; i++) wait3(NULL, WEXITE0, NULL);
t = ClockCycles() - t;
cout << "Forks scheduling time" << cycle2milisec(t)
<< " msec [" << t << " cycles]" << endl;
ClockPeriod(CLOCK_REALTIME, &clcold, NULL, 0);
exit(EXIT_SUCCESS);
}
Имитатором активной вычислительной нагрузки программы является функция workproc(), отличительной особенностью которой является то, что она при активной (хоть и бессмысленной) загрузке процессора не делает на всем интервале своего выполнения никаких системных вызовов, которые могли бы привести к вытеснению выполняющего ее потока.
Первым параметром программы является количество процессов, на которые распределяется общий объем вычислений. Но самое главное: начнем управлять размером периода временного системного тика.
ПримечаниеПо умолчанию системный тик (для QNX 6.2.1) равен 1 мсек., но в принципе его значение можно уменьшать функцией ClockPeriod()вплоть до 10 мксек. Кстати, в описании именно этой функции присутствует замечание о том, что « …период решедулирования равен 4 тикам, и это соотношение в системе нельзя изменить».
Второй параметр запуска программы (при его наличии) и определяет размер периода системного тика, выраженный в микросекундах. (В конце выполнения задач подобного рода, изменяющих размер системного тика, нужно обязательнопринять меры к восстановлению его прежнего значения даже в случаях экстремального и аварийного завершения задачи!) Для повышения достоверности тестов величина размера интервала диспетчеризации контролируется независимым образом (вызовом sched_rr_get_interval()).
При распараллеливании вычислительного объема между потоками эквивалентный код ( файл p4-2.cc) будет иметь вид (используется та же функция workproc()), которую мы повторно не показываем):
void* threadfunc(void* data) {
workproc(100);
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int numpar = 1;
if (argc > 1 && atoi(argv[1]) > 0)
numpar = atoi(argv[1]);
pthread_t *tids = new pthread_t [numpar];
_clockperiod clcold;
Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович, относящееся к жанру Интернет. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.


