Обмеження для безконтактних колекцій?


10

Девід Родрігес - dribeas написав у коментарі StackOverflow, що "Не всі колекції можна реалізувати без блокування". Я не впевнений, чи це правда, і я не можу знайти доказів в будь-якому випадку.

Це твердження не дуже точне, але дозвольте спробувати переформулювати його дещо формальніше: для кожного типу колекції Cіснує безконтактний збірник типу CLF, який пропонує той самий набір операцій, і де кожна операція на CLF має таку ж складність big-O, як і відповідна операція на C.

До речі, я не чекаю перетворень.


1
Як не експерта, мені цікаво, чи можна «чітко» визначити «без замків».
Tsuyoshi Ito

1
@Suresh: Можливо, синонім "структура даних"?
Цуйосі Іто

2
Що робити, якщо просто взяти реалізацію STM (транзакційну пам'ять програмного забезпечення), не заблоковану, та реалізувати будь-які структури даних поверх цього?
Юкка Суомела

5
@Tsuyoshi: Я думаю, що немає формального визначення безблокового замовлення. Неофіційно це означає, що ви не використовуєте інструкцію LOCK CPU, яка повільна, і дотримуватися швидшого порівняння та заміни. Оскільки LOCK можна змоделювати за допомогою порівняння та заміни, важко встановити жорстку межу між "ти, по суті, використовуєш порівняння та заміну для імітації блокування (або транзакції з цього питання)" та "о, це по-справжньому розумне використання порівняння та заміни, і зовсім не виглядає так, ніби це імітує деяку операцію вищого рівня, про яку ми знаємо ».
Раду ГРИГо

1
Наскільки я це розумію, без заблокування тут розуміється синонім неблокування. Це не стосується інструкції процесора, LOCKале планувальника потоків через mutexes / semaphores / тощо.
MSalters

Відповіді:


11

Оскільки я сам був дещо розгублений, я починаю з уточнення кількох понять у питанні.

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

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

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

Але, можете запитати, чи має це однакова складність? Я не впевнений, що питання має сенс. Розглянемо push(x) { lock(); stack[size++] = x; unlock(); }. Це постійна операція в часі? Якщо ви ігноруєте операцію блокування та, отже, інші користувачі, то можете відповісти ТАК. Якщо ви не хочете ігнорувати інших користувачів, то дійсно немає можливості сказати, чи буде натискання працювати постійно. Якщо ви перейдете на один рівень вгору і побачите, як стек використовується в якомусь конкретному алгоритмі, то, можливо, ви зможете сказати, що натискання завжди займе постійний час (вимірюється зараз з точки зору того, що станеться входом вашого паралельного алгоритму). Але це справді властивість вашого алгоритму, тому не має сенсу говорити, що push - це постійна операція в часі.

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


Я не надто впевнений у тому, чи можна насправді вважати, що pushзазначена вище операція не є постійною операцією в часі. Для фіксованої кількості процесорів і загальної реалізації lockцього не гарантується голодування, вищезазначена операція (в гіршому випадку для будь-якого даного процесора приймає N_proc * O (1), що може наївно вважатись O (1) ( кількість процесорів, що потрапляють у приховану константу)
David Rodríguez - dribeas

нf(н)f

Ну, доступ до пам'яті - це звичайний випадок. Більшість алгоритмів аналізу передбачає, що доступ до пам'яті є O (1) незалежним від використовуваної пам'яті; реальні архітектури пам'яті (з кешами тощо) краще наближені до O (log N), де N використовується пам'яттю.
MSalters

Хоча припущення, що кількість процесорів є постійною, є цілком практичним, я уникаю цього. Тоді питання полягає в тому, що складність не може бути проаналізована одновимірним способом, оскільки розмір проблеми повинен зростати як у розмірі входу, так і в кількості процесорів, які мають ортогональний розмір. Якщо припустити конкретний контейнер у стандартній бібліотеці C ++ (я, очевидно, вибираю важкий), однією з вимог є те, щоб усі елементи зберігалися в суміжному блоці пам'яті.
David Rodríguez - dribeas

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

3

Я думаю, що "КОЛЕКЦІЇ" означає "черги, стеки, зв'язані списки, дерева, ..."

Від http://www.cl.cam.ac.uk/research/srg/netos/lock-free/

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

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

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

О()

Вичерпну документацію з цього питання можна знайти в Інтернеті:

http://www.google.it/search?q=lock+free+algorithm+filetype%3Apdf

(... та подальші посилання в кінці кожного документа)

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