За замовчуванням розмір стека для pthreads


24

Як я розумію, розмір стека за замовчуванням для pthread в Linux становить 16K. Я отримую дивні результати на моїй 64-розрядної установки Ubuntu.

$ ulimit -s
8192

Також:

pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf("Thread stack size = %d bytes \n", stacksize);

Prints
    Thread stack size = 8388608 bytes

Я впевнений, що розмір стека не "8388608". Що може бути не так?


7
Я думаю 8388608 / 1024 = 8192.
cuonglm

6
Ви думаєте про 16 кб на один стек ядра . Повністю відокремлений випуск від пам'яті стека в просторі користувача. Склади ядер крихітні, тому що вони не можуть бути піддані підключення до сторінки, або ліниво виділені, і повинні бути суміжними сторінками у фізичній пам'яті. elinux.org/Kernel_Small_Stacks . Наявність надзвичайно великої кількості загальних потоків може бути проблемою для i386, де адресний простір обмежений, особливо з 8k стеками за замовчуванням для 32-розрядних.
Пітер Кордес

Відповіді:


21
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

stacksizeАтрибут визначає розмір мінімального стека (в байтах) , виділений для створеного стека ниток.

У вашому прикладі розмір стека встановлюється на 8388608 байт, що відповідає 8 МБ, як повертається командою ulimit -s Так, що відповідає.

З pthread_create()опису:

Для Linux / x86-32 стандартний розмір стека для нового потоку становить 2 мегабайти . Під реалізацією потоку NPTL, якщо обмеження програмного забезпечення RLIMIT_STACK на момент запуску програми має будь-яке значення, відмінне від "необмеженого", воно визначає розмір стека за замовчуванням для нових потоків. Використовуючи pthread_attr_setstacksize (3), атрибут розміру стека може бути явно встановлений в аргументі attr, який використовується для створення потоку, щоб отримати розмір стека, відмінний від типового.

Таким чином, розмір стека потоку можна встановити або через встановлену вище функцію, або через ulimitвластивість системи. Для 16-ти тисяч, на які ви посилаєтесь, не зрозуміло, на якій платформі ви бачили це та / або чи встановлено для цього якийсь системний ліміт.

Дивіться сторінку pthread_create і тут ви знайдете кілька цікавих прикладів із цього приводу.


47

Насправді ваш розмір віртуальної стеки - 8388608 байт (8 МБ). Звичайно, природно зробити висновок, що це не може бути правильним, оскільки це смішно великий об'єм пам'яті, яку кожен потік витрачає на її стек, коли 99% часу, що становить пару КБ, ймовірно, все, що їм потрібно.

Хороша новина полягає в тому, що ваш потік використовує лише кількість фізичної пам'яті, яка йому фактично потрібна. Це одна з магічних сил, яку ваша ОС отримує від використання апаратного блоку управління пам’яттю (MMU) у вашому процесорі. Ось що відбувається:

  1. ОС виділяє для вашого стека 8 Мб віртуальної пам’яті, встановивши таблиці сторінок MMU для вашого потоку. Для цього потрібно дуже мало оперативної пам’яті, щоб містити лише записи таблиці сторінок.

  2. Коли ваш потік запускається і намагається отримати доступ до віртуальної адреси стека, у якого ще не призначена фізична сторінка, MMU запускає апаратне виключення під назвою "помилка сторінки".

  3. Ядро ЦП реагує на виняток помилок сторінки шляхом переходу в режим привілейованого виконання (який має власний стек) і викликає функцію обробника винятків помилок сторінки всередині ядра.

  4. Ядро виділяє сторінку фізичної оперативної пам’яті цій сторінці віртуальної пам’яті і повертається назад до потоку користувальницького простору.

Нитка простору користувача не бачить жодної роботи. З його точки зору, він просто використовує стек так, ніби пам'ять була там весь час. Тим часом стек автоматично зростає (або ні) для задоволення потреб потоку.

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

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