Титла: Threads or Processes Публикувано от: Nikolavp в Nov 02, 2008, 20:18 Днес на OpenFest-a беше засегната темата за паралелното програмиране и по специално неща като OpenMP. Интересното е, че лектора през цялото време твърдеше, че ако се ползват нишки и процесорите са повече от 2(това каза, че е частен случай) и се стартира нова нишка тя няма да се поеме от свободното ядро. Искам някой по - запознат да каже дали това е така, защото няколко започнаха да задават въпроси в тази насока и лектора каза, че не е гледал кода за 2.6 ядрата. Въпроса е дали могат да се използват ресурсите пълнеценно без да форкват отделни процеси, а само нишки. Не говорим за синхронизация/репликации по мрежите, а само на една машина.
Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 20:32 Предполагам го е казал някой от BSD-частта на опенфеста :)
Не е вярно. За task scheduler-a хммм "атомичната" единица е thread, не процес. Това е следствие от факта, че в 2.6 се избира 1:1 threading модела (имплементиран в NPTL). Доколкото съм запознат в повечето БСД-та и в по-ранните соларис системи са използвали m:n модела, който просто не позволява scheduling-a на нишки в рамките на един процес да стават на повече от един процесор - грубо казано там атомарната единица е процес, но в рамките на процеса има един сложен механизъм, според който се дава процесорно време на всяка отделна нишка, въпрос на софтуерен дизайн е и има изписани материали по въпроса. Така че не го слушай този лектор, очевидно не знае какво говори :) Титла: Re: Threads or Processes Публикувано от: task_struct в Nov 02, 2008, 21:15 Хмм, аз чух като се говореше за това в коридора ама само от части и за това не се включих :)
В 2.6 ядрата се прави load-balancing на всеки 200 милисекунди и ако някое ядро не е достатъчно натоварено на него се прехвърля нишка/процес от друго но-натоварено ядро. Така че никое ядро няма да остане свободно ;) "When tasks are created in an SMP system, they're placed on a given CPU's runqueue. In the general case, you can't know when a task will be short-lived or when it will run for a long time. Therefore, the initial allocation of tasks to CPUs is likely suboptimal. To maintain a balanced workload across CPUs, work can be redistributed, taking work from an overloaded CPU and giving it to an underloaded one. The Linux 2.6 scheduler provides this functionality by using load balancing. Every 200ms, a processor checks to see whether the CPU loads are unbalanced; if they are, the processor performs a cross-CPU balancing of tasks." - http://www.ibm.com/developerworks/linux/library/l-scheduler/index.html?S_TACT=105AGX03&S_CMP=ART Титла: Re: Threads or Processes Публикувано от: Nikolavp в Nov 02, 2008, 21:18 Интересното е, че той го твърдеше супер сериозно и даже показа снимка на 7-8 процесорна машина в top, на която само единият беше натоверен до 100% от mysql заявка :). Благодаря за отговорите.
Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 21:33 Мммм не, принципно timeslice-a е 10 милисекунди - във всички x86_64 и всички ia32 ядра от няколко версии насам, за алфите и powerpc-тата продължава да е 100мс (за последното не съм 100% сигурен, може и тях да са ги минали на HZ=1000), а за разни изкривени embedded архитектури слагат дори по-нисък timeslice.
Въпросът е друг. Значи в момента в който нишките са станали нещо модерно, хората тръгнали да мислят по въпроса как да си реализират нишките. Та значи има 2 варианта това да стане - по-простият е 1:1 модела, по-сложният е m:n модела. И всички първоначално (включително линукс) са избрали по-сложният вариант. 1:1/m:n е просто съотношение на task scheduler entries към threads. В първият вариант всяка нишка е task scheduling entry - и може да се стартира по всяко време на всяко ядро. Вторият вариант е по-различен: нишките се разглеждат като подмножество на процеса и на един процесор може да се изпълнява само един процес (съответно някоя от тези n нишки). Но това означава че във всяко едно време нишките, създадени от един процес могат да вървят само на процесорът, на който върви процеса. Сега изглежда много малоумно, че хората масово са избирали m:n модела (включително линукс с linuxthreads в 2.4 времената). Това е оправдано обаче заради цената на context switching-a. Значи всичките нишки в рамките на един процес си споделят общо виртуално адресно пространство. "Скъпото" нещо на task switching-a е че може да се наложи да "превключиш" между адресни пространства (ако превключваш между различни процеси или нишки от различни процеси). Когато това стане трябва да изчистиш процесорния кеш (наричан TLB cache) и всички следващи достъпвания до РАМ-та да стават бавно и през серия от page faults. В 2.6 са работили (и още работят) по scheduling механизъм, който има предвид това и "предпочита" scheduling на процеси стига да не се налага TLB flushes по възможност, демек предпочита се ако е възможно да се превключва между нишки от един и същ процес, споделящи общо адресно пространство. Разбира се това не винаги е възможно. За сметка на това, РАМ паметта става все по-бърза и по-бърза и поради тази причина, минаването към 1:1 threading механизма се е оказало едно много прозорливо и умно решение. Чак след това някои БСД системи почват да следват примера на линукс, което е доста показателно за някои работи :) task struct, тези 200 мс за които говориш са нещо друго - това е друга дивотия на task scheduling-a, която се занимава с балансирането на smp nodes. Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 22:13 Интересното е, че той го твърдеше супер сериозно и даже показа снимка на 7-8 процесорна машина в top, на която само единият беше натоверен до 100% от mysql заявка :). Благодаря за отговорите. Е що не го запита с какво ядро върви това :) Ама най-простият пример с многонишково приложение за което мога да се сетя е хммм...примерно ktorrent. Накарай го да тегли няколко повече сийд-нати торънта и ако имаш система с повече процесори виж колко процесорна утилизация има ktorrent, щото top има тоя лош навик :) С голяма вероятност ще е над 100%. С някой j2ee application server като jboss това можеш да го забележиш доста по-лесно де :) Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 22:42 Оффф 1 милисекунда или 10 милисекунди е timeslice-a, моя е грешката като не мога да смятам като хората :)
И все пак, интересно ми е на коя лекция са говорили тия работи? :) Титла: Re: Threads or Processes Публикувано от: Nikolavp в Nov 02, 2008, 22:57 http://openfest.org/program2008
15:00 - 15:45 Barriers for scaling systems Титла: Re: Threads or Processes Публикувано от: tarator в Nov 02, 2008, 23:02 И в 2.6 и в 2.4 (доколкото си спомням и в 2.2) ядрото не прави разлика между процеси и нишки. Та лекторът е говорил глупости. :)
Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 23:13 Това е гадно :) Предпочитам да гледам на нещата по различен начин, поне що се отнася до linuxthreads :)
Сега поне нишките изглеждат истински такива :) Титла: Re: Threads or Processes Публикувано от: Nikolavp в Nov 02, 2008, 23:38 И в 2.6 и в 2.4 (доколкото си спомням и в 2.2) ядрото не прави разлика между процеси и нишки. Та лекторът е говорил глупости. :)Яко :). А аз си помислих, че това което съм чел са били глупости :). Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 02, 2008, 23:46 Тараторът е лош :) Ядрото прави разлика, независимо дали става въпрос за 2.2, 2.4. или 2.6. Просто нещата стават по различен начин, а това което top докладва е съвсем отделен въпрос :)
Титла: Re: Threads or Processes Публикувано от: tarator в Nov 03, 2008, 00:42 Ядрото _не прави_ никаква разлика между тредове и процеси. И двете се създават с clone, а не стават "по различен начин". Единствената разлика, която 2.6 прави е да не показва всички тредове директно в /proc.
Между другото, не си спомням някога linuxthreads да е имплементирало н:м модел. Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 03, 2008, 01:04 Създават се с clone2(), обаче върху процесорите се скедюлират по различен начин. Linuxthreads си има нишка, която наглежда и менажира останалите нишки. Сега не знам ама за мен това свежда нещата до недостатъците на mxn модела. Примерно създай нова нишка или утрепи такава и кажи кога това ще се случи наистина. Реално погледнато, що се отнася до първоначалният проблем в заглавието на темата дали когато създадеш нишка тя веднага ще се изпълнява на друг процесор или не - имплементацията на linuxthreads според мен в това отношение се държи като m:n такава.
Титла: Re: Threads or Processes Публикувано от: tarator в Nov 03, 2008, 01:07 linuxthreads _не_ менаджира останалите нишки, погледни пак имплементацията в glibc. Единствените случаи когато glibc прави някаква синхронизация между нишките е когато някоя от тях извика seteuid или подобна команда.
За м:н може да се говори ако част от нишките вървят в един процес, обикновено в такъв случай има начин да се създават процесни нишки или вътрешнопроцесни. В pthreads такъв вариант няма. libthread на Plan9 дава такава възможност -- createproc и createthread. Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 03, 2008, 01:16 Абе човек те дефакто вървят като нишки в рамките на един процес. Цялата тарапана по създаване на нови нишки, премахването им и синхронизацията между тях изисква на някой процесор да се изпълни това, което прави управляващата нишка. Демек не се ли скедюлира тази нишка, операциите със всички останали нишки стоят и чакат докато task scheduler-a благоволи да изпълни нишката, която ги управлява.
Добре, реално погледнато всичките си имат отделни PID-ове и биха могли след създаването си да работят на отделни процесори. Обаче за да работят, всичките им синхронизационни примитиви и всичките операции по създаване/убиване на нишки за да се изпълнят, трябва на някой процесор да се изпълни нишката,която ги управлява. Каквото и да говорим, NPTL е по-добър механизъм това да стане, защото НЯМА нужда такава нишка да се изпълнява, такава нишка няма и ролята и се поема от ядрото. Добре, това не е точно mxn модел. Определено обаче не е и истинска имплементация на 1:1 модел, всичко зависи от една нишка за всички процеси които имат ендакъв PPID. Титла: Re: Threads or Processes Публикувано от: tarator в Nov 03, 2008, 01:49 Създаването и премахването на нишки не са "чести" събития и не се изпълняват от една определена нишка. Нишката, която се опитва да създаде нова нишка се грижи за синхронизирането с останалите, ако то е необходимо (става с пращане на сигнали). През останалото време нишките си вървят напълно независимо една от друга. Затова и моделът няма нищо общо с н:м.
Между другото дори и при NPTL нишките се синхронизират при setuid и компания. Което е доста малоумно и се случват доста races. Скоро ми се налага да викам директно SYS_seteuid защото ако викам glibc функцията понякога всички нишки забиваха. Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 03, 2008, 09:02 Да, но само една нишка се грижи за синхронизацията между всички останали :) В смисъл една нишка освобождава lock-а, праща сигнал към менажиращата и тя има грижата да разпрати сигнали до всички останали които спят, за да ги "събуди" и натика в runqueue. Тоест механизма си зависи дали менажиращата нишка ще й се даде процесорно време.
А и добре, създаването и премахването са редки събития, но изчакването на други нишки не е чак толкова рядко :) Добре де предавам се, знам че си прав, но пак казвам, че linuxthreads е направен тъпо и при определени положения се държи точно както m:n. При setuid()....защо? Титла: Re: Threads or Processes Публикувано от: tarator в Nov 03, 2008, 16:41 Кое изчакване точно? Защото mutexes и conditions, които също водят до "изчакване" не се управляват от една нишка.
Няма нужда да се предаваш, ние просто си спорим. Аз не претендирам да знам в подробности linuxthreads преди NPTL защото не ми се е налагало да гледам имплементацията в дълбочина. Титла: Re: Threads or Processes Публикувано от: gat3way в Nov 03, 2008, 18:17 Ммм доколкото аз знам в linuxthreads има нишка, която се занимава със синхронизацията между останалите. Примерно една нишка освободи мутекс, за да "разберат" останалите трябва първо на някой процесор да се изпълни тази нишка и тя да изпрати съответните сигнали към останалите нишки, чакащи този мутекс.
При NPTL, това е премахнато и вместо това има някакъв друг (futex) механизъм при който се избягва посредничеството на една менажираща нишка. За целта има една (споделена) променлива, чиято стойност се използва за целите на локинга. Има дефинирани syscalls за "заключване"/"отключване" и "чакане" на тази стойност да се промени. Ядрото се намесва в цялата картинка така, че когато има повече от една чакаща нишка за един футекс и когато той се "отключи", да събуди някоя определена от тези нишки. Така тарапаната около изпращането на сигнали между нишки и менажиращата нишка се елиминира. Така не се налага "отключването" и "заключването" да става на цената на това някъде тази менажираща нишка да се изпълни някъде. Защото ако всички нишки (без една) от програмата трябва да изчакат изпълнението на менажиращата такава, за да ги арбитрира, то тогава на практика става същото като при m:n трединга - там нали за да се изпълни някоя нишка, трябва процесът й да се изпълни върху някой процесор. Обаче аз не си давам сметка, че разглеждам случай в който всички нишки изчакват една да освободи мутекса, което не е задължително и зависи до голяма степен от това какво прави кода. Значи разглеждам по-скоро един случай, който сигурно е възможно най-лошият (предполагам) в linuxthreads (и при който в NPTL нямаме такъв проблем). |