Чому загальний стан погіршує ефективність роботи?


19

Я працюю за принципом одночасного програмування. По суті, всі мої робочі потоки мають незмінні копії того самого стану, які ніколи не поділяються між собою ( навіть за посиланням ). Взагалі кажучи, це спрацювало дуже добре.

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

Питання в тому, що ... оскільки немає блокувань, чому введення цього сингтона створює хіт продуктивності? Що саме відбувається під прикриттями, що могло б це пояснити?

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


8
Ви вказали на коду профілера?
Timo Geusch

2
Профілювання навряд чи дасть відповідь на це запитання, якщо ви не профілюєте CLR та, можливо, ядро ​​Windows (непросте завдання для середнього програміста).
Ігбі Ларгеман

1
@JoeGeeky Добре тоді, я думаю, що єдине, що тут для мене потрібно зробити, - це +1 та користь! Це здається дивним, оскільки вони обидва на одному рівні непрямості зрештою, і так чи інакше повинні вписуватися в кеш-процесор тощо.
Макс

2
FWIT Я породив пару ниток і запустив кілька таймерів. Я створив клас, синглтон, lockedSingleton та dict <string, string>. Після першої інстанції кожної послідовної дії за будь-який об'єкт було потрібно близько 2000с. Словник працює 2 рази повільніше, може бути викликаний кодом конструктора ... він повільніше, ніж блокування сам по собі. Беручи до уваги всі GC, ОС, які працюють з чергою потоків потоків та іншими накладними… не впевнені, що справді можна відповісти на це питання. Але, за своїми результатами, я не вірю, що це стосується Singletons. Не, якщо він реалізований як на MSDN.Excludes оптимізації компілятора.
P.Brian.Mackey

1
@JoeGeeky - інша думка: чи використання кешу додає рівень непрямості? Якщо часто звертатись, переслідування вниз додаткового вказівника дереф (або MSIL еквівалент) може додати деякий час над локальною менш непрямою копією.
sdg

Відповіді:


8

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


3
Це звучить як false sharingсценарій, описаний вашим. Щоб виділити це, мені потрібно профілювати кеш L2. На жаль, це типові типи, тому додавання буферного простору не буде варіантом, якщо це насправді те, що відбувається.
JoeGeeky

3

Я би переконався, що Equals()і GetHashCode()методи об’єктів, які ви використовуєте як ключі до словника, не мають жодних несподіваних побічних ефектів, що не сприймають нитку. Профілювання дуже допомогло б тут.

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

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

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

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

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