Сообщение Re: Паралелльное изменение одного объекта от 09.04.2016 17:40
Изменено 09.04.2016 19:49 Sinix
Здравствуйте, e.thrash, Вы писали:
ET>Нужна ли в данном случае синхронизация?
Нет (при условии, что оба потока не разделяют друг с другом какие-либо изменяемые данные).
Но есть нюансЪ: активная запись-чтение по соседним приводит к накладным расходам на синхронизацию линеек кэша.
Воспроизвести можно, но нужно постараться.
Во-первых, на современных ноутбуках надо включать режим "максимальная производительность" и запитывать от сети. Иначе один и тот же код при последовательных запусках выдаёт 5-15% разницы, если утыкается в CPU и до 40% — если в память. Разумеется, это для коротких бенчмарков, для длинных разница сглаживается.
Во-вторых, надо угадать с аллокациями. Чтобы показать что проблема именно в линейке кэша, надо уложить два инстанса в емнип соседние 64 байт (для интелов). Не всегда удаётся, от запуска к запуску вариант TwoInstancesNear может скакать туда-сюда.
В результате получаем нечто вроде
(x64, релизная сборка, ctrl-F5).
Подробности и более-менее стабильное воспроизведение см в отличной статье от И.Островского, раздел "Example 6: False cache line sharing".
P.S. Если кто-то будет принимать какие-то решения на основе этого поста, без замеров на реальном коде — вы знаете, кто сам себе злой буратина, ок?
ET>Нужна ли в данном случае синхронизация?
Нет (при условии, что оба потока не разделяют друг с другом какие-либо изменяемые данные).
Но есть нюансЪ: активная запись-чтение по соседним приводит к накладным расходам на синхронизацию линеек кэша.
Воспроизвести можно, но нужно постараться.
Во-первых, на современных ноутбуках надо включать режим "максимальная производительность" и запитывать от сети. Иначе один и тот же код при последовательных запусках выдаёт 5-15% разницы, если утыкается в CPU и до 40% — если в память. Разумеется, это для коротких бенчмарков, для длинных разница сглаживается.
Во-вторых, надо угадать с аллокациями. Чтобы показать что проблема именно в линейке кэша, надо уложить два инстанса в емнип соседние 64 байт (для интелов). Не всегда удаётся, от запуска к запуску вариант TwoInstancesNear может скакать туда-сюда.
В результате получаем нечто вроде
SameInstance: 1506ms, ips: 331 983 907,28 | Mem: 31,81 kb, GC 0/1/2: 0/0/0 => 500000000
TwoInstances: 1245ms, ips: 401 344 632,95 | Mem: 19,05 kb, GC 0/1/2: 0/0/0 => 500000000
TwoInstancesNear: 1475ms, ips: 338 886 094,96 | Mem: 10,28 kb, GC 0/1/2: 0/0/0 => 500000000
(x64, релизная сборка, ctrl-F5).
Пруфкод | |
| |
Подробности и более-менее стабильное воспроизведение см в отличной статье от И.Островского, раздел "Example 6: False cache line sharing".
P.S. Если кто-то будет принимать какие-то решения на основе этого поста, без замеров на реальном коде — вы знаете, кто сам себе злой буратина, ок?
Re: Паралелльное изменение одного объекта
Здравствуйте, e.thrash, Вы писали:
ET>Нужна ли в данном случае синхронизация?
Нет (при условии, что оба потока не разделяют друг с другом какие-либо изменяемые данные).
Но есть нюансЪ: активная запись-чтение по соседним адресам приводит к накладным расходам на синхронизацию линеек кэша.
Воспроизвести можно, но нужно постараться.
Во-первых, на современных ноутбуках надо включать режим "максимальная производительность" и запитывать от сети. Иначе один и тот же код при последовательных запусках выдаёт 5-15% разницы, если утыкается в CPU и до 40% — если в память. Разумеется, это для коротких бенчмарков, для длинных разница сглаживается.
Во-вторых, надо угадать с аллокациями. Чтобы показать что проблема именно в линейке кэша, надо уложить два инстанса в емнип соседние 64 байт (для интелов). Не всегда удаётся, от запуска к запуску вариант TwoInstancesNear может скакать туда-сюда.
В результате получаем нечто вроде
(x64, релизная сборка, ctrl-F5).
Подробности и более-менее стабильное воспроизведение см в отличной статье от И.Островского, раздел "Example 6: False cache line sharing".
P.S. Если кто-то будет принимать какие-то решения на основе этого поста, без замеров на реальном коде — вы знаете, кто сам себе злой буратина, ок?
ET>Нужна ли в данном случае синхронизация?
Нет (при условии, что оба потока не разделяют друг с другом какие-либо изменяемые данные).
Но есть нюансЪ: активная запись-чтение по соседним адресам приводит к накладным расходам на синхронизацию линеек кэша.
Воспроизвести можно, но нужно постараться.
Во-первых, на современных ноутбуках надо включать режим "максимальная производительность" и запитывать от сети. Иначе один и тот же код при последовательных запусках выдаёт 5-15% разницы, если утыкается в CPU и до 40% — если в память. Разумеется, это для коротких бенчмарков, для длинных разница сглаживается.
Во-вторых, надо угадать с аллокациями. Чтобы показать что проблема именно в линейке кэша, надо уложить два инстанса в емнип соседние 64 байт (для интелов). Не всегда удаётся, от запуска к запуску вариант TwoInstancesNear может скакать туда-сюда.
В результате получаем нечто вроде
SameInstance: 1506ms, ips: 331 983 907,28 | Mem: 31,81 kb, GC 0/1/2: 0/0/0 => 500000000
TwoInstances: 1245ms, ips: 401 344 632,95 | Mem: 19,05 kb, GC 0/1/2: 0/0/0 => 500000000
TwoInstancesNear: 1475ms, ips: 338 886 094,96 | Mem: 10,28 kb, GC 0/1/2: 0/0/0 => 500000000
(x64, релизная сборка, ctrl-F5).
Пруфкод | |
| |
Подробности и более-менее стабильное воспроизведение см в отличной статье от И.Островского, раздел "Example 6: False cache line sharing".
P.S. Если кто-то будет принимать какие-то решения на основе этого поста, без замеров на реальном коде — вы знаете, кто сам себе злой буратина, ок?