Шматструменнасць эфектыўнасць у C ++

I am trying to learn threading in C++, and just had a few questions about it (more specifically <thread>.

Скажам, машына гэты код будзе працаваць на мае 4 ядра, я павінен падзяліць аперацыю на 4 ніткі? Калі б я стварыць 8 патокаў замест 4, будзе гэта працаваць павольней на 4 ядра машыне? Што рабіць, калі працэсар мае гиперпоточность, я павінен паспрабаваць зрабіць ніткі супадае з колькасцю фізічных ядраў або лагічных ядраў?

Ці павінен я проста не турбавацца пра колькасць ядраў машына мае, і паспрабаваць стварыць столькі патокаў, як гэта магчыма?

I apologize if these questions have been already answered; I've been looking for information about threading with <thread>, which was introduced in c11 so I haven't been able to find too much about it.

Праграма, пра якую збіраецца запусціць мноства незалежных мадэляў.

If anybody has any insight about <thread> or just multithreading in general, I would be glad to hear it.

3
Як гэтае пытанне, верагодна, занадта агульны, каб атрымаць добры адказ. Ёсць занадта шмат невядомых пра тып апрацоўкі, план падзелу працы, архітэктуры працэсара, аперацыйнай сістэмы і планавальніка, і г.д., каб даць канкрэтную рэкамендацыю.
дададзена аўтар Adrian McCarthy, крыніца
@JesusRamos так бы мовіць, я бег 1000 мадэлявання, кожны з мадэлявання з лінейным часам. Ці будзе стварэнне патоку для кожнай мадэлі будзе празмернасцю? Ці будзе гэта на самай справе павялічыць хуткасць, ці ж накладныя выдаткі ад стварэння тэмы выклікаюць зніжэнне прадукцыйнасці?
дададзена аўтар Steven Morad, крыніца
Стварыць столькі патокаў, колькі вам трэба, гэта агульнае правіла, ці, прынамсі, зрабіць яго наладжвальным, калі вы сапраўды хочаце, каб адпавядаць колькасці ядраў на машыне, але памятайце, што ваша прыкладанне не з'яўляецца адзіным працэсам, запушчаным на машыне.
дададзена аўтар Jesus Ramos, крыніца
Гэта залежыць ад таго, вы, магчыма, прыйдзецца зрабіць некаторыя тэсты, але калі яны вылічальная інтэнсіўнае клюшку колькасць ядраў. Калі яны I/O ці нешта звязанае затым разгледзець даданне больш збалансаваць той факт, што некаторыя патокі будуць спаць у чаканні аперацыі, каб скончыць.
дададзена аўтар Jesus Ramos, крыніца
Таксама адзначым, што з-за блакавання аперацый, аптымальнае колькасць патокаў можа быць <�я> вышэй , чым колькасць лагічных ядраў.
дададзена аўтар Mooing Duck, крыніца
Прыдзіркі: не <threads.h> у C ++ 11: гэта <�нітка> .
дададзена аўтар syam, крыніца
@StevenMorad: гл адказ Аррьета ст. Калі вашы разлікі CPU вокладцы, то гэта бескарысна спараджаць больш патокаў, чым у вас ёсць ядра. Калі яны I/O вокладцы, то вы, верагодна, варта спараджаць адзін паток на задачу. Ва ўсіх выпадках тэст! Пытанні кэша можа запаволіць Вас таксама шмат ( «ілжывае падзел»), няма адназначнага адказу на ваша пытанне.
дададзена аўтар syam, крыніца
Ды ключ тут, каб усвядоміць, як аперацыйная сістэма разліку часу для кожнага патоку, каб выдаткаваць на працэсар. Кожная АС мае алгарытм планавання, так што майце гэта на ўвазе, як добра. en.wikipedia.org/wiki/Scheduling_(computing)
дададзена аўтар Connor Hollis, крыніца

6 адказы

Калі вы выконваеце чыстыя разлікі, без уводу/высновы - і гэтыя разлікі асобна стаяць і не спадзявацца на вынікі іншых разлікаў, якія адбываюцца ў іншым струмені, максімальны лік такіх нітак павінна быць лік ядраў (магчыма, адзін ці два менш, калі сістэма таксама загружаецца з іншымі задачамі).

Калі вы робіце сетку ўвод/выснова або падобны, больш патокаў, безумоўна, магчыма.

Калі вы робіце дыск-I/O, адзін паток чытання з дыска часта лепш, таму што дыск чытае з некалькіх патокаў прыводзіць да перамяшчэння галоўкі чытання/запісы вакол на дыску, які толькі робіць рэчы больш павольна.

Калі вы выкарыстоўваеце тэмы для, каб зрабіць код больш простым, то лік патокаў, верагодна, залежыць ад таго, што вы робіце.

Гэта таксама залежыць ад таго, як «аўтаномнага» кожнага патоку. Калі яны павінны абменьвацца дадзенымі ў складаных адносінах, абмен/у чаканні другога патоку/і г.д., можа таксама зрабіць яго больш павольна, з вялікай колькасцю нітак.

І, як ужо казалі іншыя, спрабуюць зрабіць вашу аснову для гэтага гнуткага і тэставаць розныя варыянты. Пераважна на некалькіх машынах (калі ў вас ёсць толькі адзін выгляд машыны, якую вы калі-небудзь запусціць свой код на).

4
дададзена

There is no such thing as <threads.h>, you mean <thread>, the thread support library introduced in C++11.

Адзіны адказ на ваша пытанне «тэст і ўбачыць». Вы можаце зрабіць свой код досыць гнуткім, так што ён можа быць запушчаны пры прапусканні N параметр (дзе N гэта жаданае лік нітак).

Калі вы CPU пераплёту, то адказ будзе вельмі адрознівацца ад выпадку, калі вы IO звязаныя.

Такім чынам, тэст і паглядзець! Для даведкі, гэтай спасылкі можа быць карыснай . А калі сур'ёзна, то ісці наперад і атрымаць гэтую кнігу . Шматструменнасць, паралелізм, і падобная валасатая тэма.

3
дададзена

Не думайце, што колькасць патокаў, якія неабходна, як у параўнанні з машынай, вы працуеце на. Наразанне разьбы valuablue ў любы час у вас ёсць працэс, што:

A: Існуе некалькі вельмі павольнай аперацыі, што астатняя частка працэсу не трэба чакаць.

B: Некаторыя функцыі могуць працаваць хутчэй, чым адзін аднаго і не павінны выконвацца инлайн.

C: Існуе шмат не парадку залежнага I/O адбываецца (вэб-сервера).

Такія толькі некаторыя з відавочных прыкладаў пры запуску нітка мае сэнс. Такім чынам, лік патокаў запускаюць у большай ступені залежыць ад колькасці гэтых сцэнарыяў, якія ўсплываюць ў вашым кодзе, чым архітэктура вы чакаеце працаваць на. На самай справе, калі вы не бяжыце працэс, які сапраўды сапраўды павінен быць аптымізаваны, цалкам верагодна, што вы можаце толькі крон з некалькіх працэнтных пунктаў дадатковай прадукцыйнасці шляхам параўнальнага аналізу для вашай архітэктуры ў параўнанні з колькасцю нітак, якія вы запускаеце, і у сучасных кампутарах гэты лік не павінна мяняцца наогул.

Давайце разгледзім прыклад ўводу/высновы, як гэта сцэнар, які будзе ўбачыць максімальную карысць. Давайце выкажам здагадку, што нейкая праграма патрэбна для звязка з 200 карыстальнікамі па сетцы. Network I/O вельмі і вельмі марудна. Тысячы разоў павольней, чым працэсар. Калі б мы павінны былі апрацоўваць кожны карыстальнік, у сваю чаргу, мы б марнаваць тысячы цыклаў працэсара толькі ў чаканні дадзеных прыйсці ад першага карыстальніка. Маглі б мы не былі апрацоўкі інфармацыі з больш чым адной карыстальніка, у той час? У гэтым выпадку, так як у нас ёсць каля 200 карыстальнікаў, а таксама дадзеныя, якія мы чакаем, мы ведаем, што 1000s раз павольней, чым тое, што мы можам справіцца (мяркуючы, што мы маем мінімальны аб'ём апрацоўкі, каб зрабіць на гэтых дадзеных), мы павінны запусціць столькі патокаў, колькі дазваляе аперацыйная сістэма. Вэб-сервер, які выкарыстоўвае перавагі шматструменнасці можа абслугоўваць сотні больш людзей у секунду, чым той, які не робіць.

Зараз давайце разгледзім менш I/O інтэнсіўны прыклад, дзе ў нас ёсць некалькі функцый, якія выконваюцца, у сваю чаргу, але незалежны адзін ад аднаго, і некаторыя з іх могуць працаваць хутчэй, скажам, таму што дыск I/O ў адным, і няма дыскавы ўвод/выснова ў іншым. У гэтым выпадку наша I/O па-ранейшаму даволі хутка, але мы, вядома, марнаваць час апрацоўкі чакае дыск, каб дагнаць. Такім чынам, мы можам запусціць некалькі патокаў, проста скарыстацца нашай вылічальнай магутнасцю, і звесці да мінімуму страты цыклаў. Тым не менш, калі мы запусцім столькі патокаў, колькі аперацыйная сістэма дазваляе нам, хутчэй за ўсё, cuase пытанні кіравання памяццю для філіялаў прадказальнікаў, і г.д. ... і запуск занадта шмат патокаў у гэтым выпадку на самай справе субоптимальным і можа запаволіць працу праграмы. Звярніце ўвагу, што ў гэтым, я ніколі не казаў, колькі ядраў у машыны ёсць! Не тое, што аптымізацыя для розных архітэктур ня каштоўна, але калі вы аптымізаваць для адной архітэктуры вы, верагодна, вельмі блізкія да аптымальных для большасці. Мяркуючы, што, зноў-такі, што вы маеце справу з усімі досыць сучаснымі працэсарамі.

2
дададзена
<�Р> Скажам, машына гэты код будзе працаваць на мае 4 ядра, я павінен падзяліць аперацыю на 4 ніткі? </Р>

Калі некаторыя часткі кода могуць выконвацца паралельна, то так, гэта можа быць зроблена, каб ісці хутчэй, але гэта вельмі складана зрабіць, так як нагрузкі патокаў і камутацыі дадзеных паміж імі займае масу часу.

<�Р> Калі б я стварыць 8 патокаў замест 4, будзе гэта працаваць павольней на 4 ядра машыне? </Р>

Гэта залежыць ад кантэксту пераключэння ён павінен рабіць. Часам выкананне будзе пераключацца паміж патокамі вельмі часта і часам гэта не будзе, але гэта вельмі цяжка кантраляваць. Ён не будзе ў любым выпадку працаваць хутчэй, чым 4 патоку робяць тую ж працу.

<�Р> Што рабіць, калі працэсар мае гиперпоточность, я павінен паспрабаваць зрабіць ніткі супадае з колькасцю фізічных ядраў або лагічных ядраў?

Hyperthreading працуе амаль гэтак жа, як якія маюць большую колькасць ядраў. Калі вы заўважыце розніцу паміж рэальным ядром і ядром выканання, вы будзеце мець дастаткова ведаў, каб абыйсці засцярогі.

<�Р> Ці павінен я проста не турбавацца пра колькасць ядраў машына мае, і паспрабаваць стварыць столькі патокаў, колькі магчыма?

NO, ніткі цяжка кіраваць, пазбягаць іх столькі, колькі вы можаце.

<�Р> Праграма, пра якую збіраецца запусціць мноства незалежных мадэляў.

Вы павінны глядзець у OpenMP . Гэта бібліятэка C зроблена для распаралельвання вылічэнняў, калі ваша праграма можа быць падзелена. Не блытайце паралельна з адначасовым. Паралельнае гэта проста некалькі патокаў працуюць разам, паралельна зроблена спецыяльна для паскарэння вашага прыкладання. Можа быць, OpenMP з'яўляецца празмернасцю для вашай рэчы, але гэта добрая рэч, каб ведаць, калі вы набліжаецеся паралельныя вылічэнні

1
дададзена

Я думаю, што большасць людзей кажуць, што буйнамаштабныя праекты пранізлівых лепш падтрымліваюцца іншымі, чым з мовамі ++ (ісці, Scala, CUDA). Задача паралелізм, у адрозненне ад паралельнасці дадзеных працуе лепш у C ++. Я б сказаў, што вы павінны стварыць столькі патокаў, колькі ў вас ёсць задачы раздаваць, але калі дадзеныя паралелізм ў большай ступені звязана з вашай праблемай разгледзець пытанне, можа быць, з дапамогай CUDA і сувязь з астатняй часткай вашага праекта на больш позні час
Заўвага: калі вы паглядзіце на нейкі сістэмы маніторынгу вы заўважыце, што там, верагодна, значна больш, чым 8 патокаў працуе, я глядзеў на маім кампутары, і ён меў сотні патокаў, выкананых на адзін раз, так што не турбуйцеся занадта шмат пра накладных выдатках. Асноўная прычына, я выбіраю кажучы ўжо пра іншых мовах з'яўляецца тое, што кіраванне некалькімі патокамі ў C ++ або C, як правіла, вельмі цяжка і памылак, я не згадваў пра гэта, таму што з праграмай ++ будзе працаваць больш павольна (што калі вы не выкарыстоўваеце CUDA гэта, верагодна, выйграў » т)

1
дададзена
Гэта, безумоўна, тое, што я думаў. Я проста хацеў, каб даследаваць просты спосаб паралельнасці, перш чым скакаць ў выкарыстанні CUDA і г.д.
дададзена аўтар Steven Morad, крыніца
«Гэта было сотні патокаў, выкананых адразу» - вы маеце на ўвазе гэта былі сотні нітак існуе адразу, то ёсць. наўрад ці гатовы/бег.
дададзена аўтар Martin James, крыніца
@aaronman - CUDA, добра :)
дададзена аўтар Martin James, крыніца
Нічога пра C ++ не проста, мне падабаецца мова, але тэмы на некаторых новых мовах нашмат больш лёгкі вага і, такім чынам, вы можаце стварыць 1000-х з іх з невялікімі выдаткамі
дададзена аўтар aaronman, крыніца
@MartinJames, а мой кампутар 392 ядраў CUDA, так што я на самой справе, хутчэй за ўсё, правільна
дададзена аўтар aaronman, крыніца

У дачыненні да Гиперпоточность дазвольце мне пракаментаваць тое, што я знайшоў з вопыту.

У вялікім шчыльнай матрыцы множанне Hyper-Threading фактычна дае горшы прадукцыйнасць. Напрыклад Эйген і MKL абодва выкарыстоўваюць OpenMP (прынамсі, як я выкарыстаў іх) і атрымаць лепшыя вынікі па маёй сістэме, якая мае чатыры ядра і Hyper-Threading, выкарыстоўваючы толькі чатыры тэму, а не восем. Акрамя таго, у маім ўласным кодзе GEMM, які атрымлівае больш высокую прадукцыйнасць, чым Эйген я таксама атрымаць лепшыя вынікі, выкарыстоўваючы чатыры патоку замест восем.

Тым не менш, на мой Мандельброта малюнак кода я атрымліваю вялікі прырост прадукцыйнасці з дапамогай Hyper-Threading, з дапамогай OpenMP (восем патокаў замест чатырох). Агульная тэндэнцыя (да гэтага часу), здаецца, што калі код працуе добра, выкарыстоўваючы графік (статычны) у OpenMP затым Hyper-Threading не дапамагае і нават можа быць горш. Калі код працуе лепш, выкарыстоўваючы графік (дынамічны) затым Hyper-Threading можа дапамагчы.

Іншымі словамі, маё назіранне да гэтага часу з'яўляецца тое, што калі падчас выканання кожнага патоку можа мяняцца шмат Hyper-Threading можа дапамагчы. Калі падчас выканання кожнага патоку пастаянна, то гэта можа нават зрабіць прадукцыйнасць горш. Але вы павінны праверыць і паглядзець, для кожнага выпадку.

0
дададзена