Чи використовують нитки віртуальної пам'яті чи реальної пам'яті?


10

Я намагався оптимізувати свій сервер Linux для обробки 10000 потоків за процес, а зараз це лише 382. Згідно з цією статтею, для з'ясування загальних можливих потоків використовується наступна формула:

number of threads = total virtual memory / (stack size*1024*1024)

Це означає, що потоки зберігають усі свої дані у віртуальній пам'яті. І наскільки мені відомо, віртуальна пам'ять - це обмінні місця в машині Linux, яка зберігається на жорсткому диску, ніж оперативна пам'ять або кеш.

Тому моє запитання полягає в тому, чи наші потоки використовують жорсткий диск для зберігання для обробки / зберігання його даних.

Якщо так, то чи не робить це ефект? Чи можемо ми підвищити продуктивність, додавши їх до оперативної пам’яті чи кешу? Як?

Якщо ні, як саме працюють нитки?

Оновлення:

Відповідно до марної відповіді , віртуальна пам'ять - це система, що складається приблизно з:

  • фізична пам'ять (ОЗП)
  • будь-які файли свопінгу
  • апаратне забезпечення для перекладу віртуальних у фізичні адреси та видачі помилок сторінки, коли віртуальна адреса недоступна у фізичній пам'яті
  • Підтримка програмного забезпечення (ядра) для: керування таблицями пошуку, використовуваним цим обладнанням, що обробляє ці помилки сторінки, витягуючи сторінки з підкачки на вимогу

Таким чином, все, що знаходиться у віртуальній пам'яті, знаходиться разом на RAM (реальна пам'ять) та жорсткий диск (Swap Files). І як пояснює Джеймс у своїй відповіді, рішення щодо Ram проти HDD приймає Kernel за допомогою таких алгоритмів, як LRU.


2
якщо ваш сервер не має 10 000 ЦП / ядер, ви витрачаєте свій час.

@JarrodRoberson: Будь-яке, чому це?
dragosrsupercool

3
10 000 потоків - це не гарний спосіб зробити масштабність, це хороший спосіб змусити сканувати сервер, більше 1 потоку на процесор або Core просто збирається переключити контекст сервера і працювати повільніше, а не швидше.

Зокрема, коли ви говорите "намагається оптимізувати мій Linux-сервер" - що ви намагаєтесь оптимізувати? Якщо це пропускна здатність, то, можливо, один потік на процесор з мультиплексуванням і неблокуючим входом / виводом буде кращим.
Марно

Відповіді:


12

Наскільки мені відомо, віртуальна пам'ять - це обмінністю місця в машині Linux

Ні, віртуальна пам'ять - це система, що складається приблизно з:

  • фізична пам'ять (ОЗП)
  • будь-які файли свопінгу
  • апаратне забезпечення для перекладу віртуальних у фізичні адреси та видачі помилок сторінки, коли віртуальна адреса недоступна у фізичній пам'яті
  • (ядро) програмне забезпечення для:
    • управління таблицями пошуку, використовуваними цим обладнанням
    • поводження з тими помилками сторінки, витягуючи сторінки із заміни на вимогу

Це ядро, щоб переконатися, що потрібна віртуальна пам'ять є кешованою в ОЗП, коли ви цього хочете - якщо ви не пишете свій власний рівень VM простору користувача (наприклад, бази даних часто це робиться, iiuc), просто не турбуйтеся про це.


Гаразд, моє припущення щодо віртуальної пам'яті було неправильним. У будь-якому випадку швидке запитання. Чи вплине на максимальну ефективність максимальних потоків, якщо простір SWAP перевищує оперативну пам’ять?
dragosrsupercool

@dragosrsupercool: ваш обмінний простір завжди буде більшим, ніж фізична пам'ять, інакше потрібно використовувати віртуальну пам'ять.
Брайан Оуклі

1
@BryanOakley: Це не обов'язково правда. Деякі ОС виділяють сторінку своп для кожної виділеної віртуальної сторінки (тобто своп повинен бути як мінімум таким, як фізичний). Інші ОС виділяють сторінку підкачки лише тоді, коли є необхідність перемістити сторінку з фізичної пам'яті (тобто своп може бути меншим, ніж фізичний). Перевага колишнього полягає в тому, що якщо розподіл вдалося, то поміняючи цю пам'ять завжди успішно. Перевага останнього полягає в тому, що вам не потрібно песимістично розподіляти величезні файли свопу для обліку порівняно рідкісних ситуацій.
mcmcc

1
@dragosrsupercool, на продуктивність не впливатиме кількість оперативної пам’яті, своп або співвідношення між ними, якщо ви не маєте низької оперативної пам’яті та фактичної сторінки. sar може розповісти вам про діяльність підключення iirc (перевірено: sar -Bв Linux).
Марно

@Useless: Я хочу збільшити кількість потоків, поки я повністю не використаю оперативну пам’ять і не почну пейджінг.
dragosrsupercool

14

Якщо нитка насправді працює, то поточна інструкція та будь-які змінні, якими користується потік, повинні знаходитись у фізичній пам'яті.

Більшість (насправді майже всі) програм знаходяться у віртуальній пам'яті, і більшість програм використовують віртуальну пам'ять для зберігання змінних.

Віртуальні адреси, організовані в шматки, що називаються сторінками (зазвичай це 4096 або 8192 байт-блоки).

У будь-який момент часу кожен блок віртуальної пам’яті зберігається десь у реальній пам'яті або на диску в «відміненому для цього просторі».

Ваш програмний код має справу з віртуальними адресами, коли ви підключаєтесь до віртуальної адреси або запитуєте доступ до сховища за віртуальною адресою, система (як правило, на апаратному рівні) визначає поточне місцезнаходження запиту адреси та відображає його до вашої віртуальної адреси, якщо адреса на даний момент знаходиться на диску, вона перетворює її в реальну пам'ять, а потім відображає адресу.

Очевидно, коли використовується вся фізична пам’ять, якщо щось підключено до цього, тоді потрібно щось інше підключити, тому система шукає сторінку "Найменше нещодавно використані" та копіює її на диск, перш ніж скопіювати потрібну сторінку.

У сучасних системах існує кілька оптимізацій та хитрощів, пов’язаних із віртуальним зберіганням.

  • Адреси відображаються на основі принципу "за процес", тому, наприклад, усі програми C у вікні Linux запускають "основний" процес за тією ж адресою.
  • Це може дозволити декільком 32-бітовим процесам займати та використовувати набагато більше 4 Гб на машині, оскільки 32-бітова віртуальна адреса може бути відображена на реальну 64-бітну адресу.
  • Коли процеси закінчуються, або пам'ять інакше "вільна", система просто позначає сторінки як вільні, вони ніколи не копіюються назад на диск обміну.
  • Аналогічно, коли запитується новий блок зберігання, система просто захоплює безкоштовну сторінку в реальній пам'яті, ні, IO диска відбувається.
  • Функції сну та сплячого режиму примушують копіювати всю пам’ять у простір, щоб усі поточні процеси та вміст поточної пам’яті відтворювалися під час пробудження.

3
"Зрозуміло, що" всі програми C у вікні Linux запускаються [головна] з однієї адреси "не враховують рандомізацію макета адресного простору. Сьогодні це все більше використовується для запобігання різних схем атаки, що розбивають стеки. Гарна відповідь інакше, тому +1.
CVn

7

Перш за все, вам потрібно прочитати більше про пам'ять комп’ютера , оскільки вам здається, що не вистачає знань у цій галузі.

Нитка виконання - це найменша одиниця обробки, яка може бути запланована операційною системою. Реалізація потоків та процесів відрізняється від однієї операційної системи до іншої, але в більшості випадків потік міститься всередині процесу. Кілька потоків можуть існувати в межах одного процесу та обмінюватися ресурсами, такими як пам'ять, тоді як різні процеси не діляться цими ресурсами.

Отже, нитки збираються використовувати доступну пам'ять - незалежно від того, який тип наявного є. Скільки потоків ви можете запустити, залежить від розміру пам'яті та кількості пам'яті, необхідної для потоку. Якщо нитка використовує купу (не тільки стек), то їй потрібно більше пам'яті, і в цьому випадку ви можете запустити менше потоків.


@VJonvic: +1 для пояснення основної теми.
dragosrsupercool

6

Проста відповідь на ваше запитання полягає в тому, що вони використовують віртуальну пам'ять. все використовує віртуальну пам'ять, за винятком кількох процесів, пов'язаних з ОС.

З іншого боку, коли ваш потік (або будь-який потік, у будь-якому процесі) насправді працює, він використовує фізичну пам'ять. Сторінки пам'яті, пов'язані з цим процесом, заміняються на фізичну пам'ять, де процесор виконує свою роботу.


3

Віртуальна пам'ять - це ваша оперативна пам’ять, а також обмінні місця. Віртуальний просто означає, що адреса, яку бачить ваша програма, відрізняється від адреси, яку бачить чіп оперативної пам'яті. Якщо вам потрібно отримати доступ до пам’яті свопом, ОС спочатку перемістить її в оперативну пам’ять. Якщо ви не хочете жодної заміни, просто вимкніть її. Якщо у вас є достатня кількість оперативної пам’яті, вона вам не потрібна.

Якщо говорити, якщо у вас є 10 000 основний процесор, збільшення до 10 000 потоків насправді не є "оптимізацією". Після того, як у вас буде достатньо ниток для споживання всіх ядер, а також запасних або двох для, коли ці потоки заблоковані, додавання більшої кількості потоків знижує продуктивність через помилки перемикання та кеш-помилок. Ви все ще можете використовувати більше потоків, якщо це спрощує логіку вашої програми, але ви будете торгувати продуктивністю.


Так, 10 000 - це занадто багато, оскільки мій сервер є 32-бітовою одноядерною машиною. Насправді, потоки - це не тотальний процесор. Вони є потоками сканерів, тому їм би хотілося іноді чекати відповіді сервера. Я прагну переконатися, що процесор повністю зайнятий, але не перевантажений і не перевантажений. Але я все ще не розумію, як я можу знати, чи CPU схожий на безкоштовний або повністю зайнятий. Чи є якийсь інструмент чи команда?
dragosrsupercool

Я думаю, ви можете отримати цю інформацію з topкоманди.
Карл Білефельдт

@KarlBieledeldt: так, саме це я шукав. Ще одне наступне питання: я щойно прийшов із ідеєю сканування, що якщо хтось як один потік може відправити запит на URL, а інший отримує відповідь сервера, то я можу тримати Висока ефективність процесора без використання занадто багато потоків. Це можливо? Як надіслати запит з одного потоку, отримуючи відповідь на інший потік?
dragosrsupercool

2

оптимізувати мій сервер Linux для обробки 10000 потоків за процес

Як пояснили інші, це взагалі неправильно. Нитка є дорогим ресурсом , в зокрема , тому , що він має свій власний стек викликів ( як правило, мегабайт) , а тому , що це планована завдання ядра. Нитки коштують навіть дорожче, ніж відкриті дескриптори файлів .

Прочитайте Операційні системи: Три простих фрагменти (підручник, що безкоштовно завантажується).

Як правило, ви не хочете мати багато ниток, і, звичайно, не багато запущених ниток. Кількість ниток, що можна виконати, як правило, повинна бути не більше кількості ядер (або малого кратного цього числа), тобто максимум близько десятка. Кількість потоків у процесі може бути трохи більшою. Тому, якщо у вас дуже розширюваний сервер (з багатьма процесорними розетками та ядрами), ви не хочете мати у своєму процесі більше десятка потоків, що можна виконувати, і сто потоків (більшість з яких простоюють) (на робочому столі) .

У Linux потоки та процеси дуже схожі (оскільки обидва можуть бути створені клоном (2) ), і обидва є завданнями, запланованими ядром. Насправді планувальник ядра планує завдання планування, які можуть бути потоками всередині якогось багатопотокового процесу, або єдиний головний потік однопотокового процесу (у такому випадку ви назвете "обробити" цей єдиний потік) або потоки ядра. Напевно, ви не хочете, щоб на вашому робочому столі було загалом більше тисячі завдань, які можна запланувати.

У Linux процес є просто групою потоків, що обмінюються тим самим віртуальним адресним простором (і спільним доступом до деяких інших речей, таких як таблиця дескрипторів файлів тощо). Деякі процеси мають лише одну нитку.

ВАП буде визначено Вікіпедією , як

"набір діапазонів віртуальних адрес, які операційна система робить доступними для процесу"

(але див. також цю відповідь, що пояснює, що термінологія не є універсальною, і в деяких документах Microsoft використовується інше і несумісне визначення).

В Linux, proc (5) корисно зрозуміти віртуальний адресний простір деяких процесів. Спробуйте
cat /proc/self/mapsі cat /proc/$$/mapsв терміналі. Дивіться також це , а також pmap (1) & ps (1) & top (1) .

Усі програми в просторі користувачів працюють у певному процесі та використовують віртуальну пам'ять, тому кожен процес має власний віртуальний адресний простір. Фізична ОЗУ - це ресурс, яким керує ядро ​​Linux, а додатки не мають прямого доступу до оперативної пам’яті (за винятком mmap (2) -ing /dev/mem, див. Mem (4) ).

Тому процес не використовує безпосередньо оперативну пам'ять. Він використовує віртуальну пам'ять і має власний віртуальний адресний простір. Ядро використовує пейджинг для управління фізичної пам'яті сторінок і забезпечує віртуальний адресний простір і процес абстракції . У будь-який час (навіть коли ваш процес працює в режимі очікування або коли він працює) ядро ​​може розгорнути деякі сторінки (наприклад, поміняти їх на диску). Ядро конфігурує MMU (і обробка сторінки пропускає апаратні винятки в деяких обробниках переривань , або шляхом отримання сторінки з диска, або шляхом поширення помилки сегментації в процесі, див. Сигнал (7) )

Ви можете мати зелені нитки над системними потоками (але бібліотеки зелених ниток важко реалізувати та налагоджувати). Подивіться на гороутини, які використовуються в Go для привабливого прикладу. Див. Також setcontext (3) .

Іноді ваша система може експериментувати з молотком . Це відбувається, коли загальна віртуальна пам'ять (необхідна всім процесам) перевищує - за великим фактором - наявну фізичну оперативну пам'ять. Тоді ваш комп’ютер стає безвідповідальним. Читайте про розмір набору резидентів , пейджинг попиту , робочий набір , перевиконання пам’яті , ASLR .

Дивіться також -для Linux- fork (2) , клон (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , облікові дані (7) , pthreads (7) , futex (7) , можливості (7) .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.