Re[7]: Внимание, Java!
От: Nik_1 Россия  
Дата: 20.07.10 10:58
Оценка:
Здравствуйте, Ikemefula, Вы писали:
I>Тоже можно Издержки разные, на порядок по времени например только из за медленной компиляции.
Это решается установкой разработчику нормального компа На современных четырехядерниках даже большие проекты компилятся довольно быстро.
Re[8]: Внимание, Java!
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.07.10 11:07
Оценка:
Здравствуйте, Nik_1, Вы писали:

I>>Тоже можно Издержки разные, на порядок по времени например только из за медленной компиляции.

N_>Это решается установкой разработчику нормального компа На современных четырехядерниках даже большие проекты компилятся довольно быстро.

5 минут — это чудовищно много.

Кроме того, для джавы и дотнета очень много самых различных тулов в силу синтаксиса.
Re[28]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 11:18
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>Intelocked-операции всю скорость съедят. В моём тесте с С++ один только interlocked exchange на refcounter'е в std::string уже тормозит больше, чем код на Java.

CC>>Интерлокед там 1 на деаллокацию и только в случае деаллокации из не родного потока. Это довольно редкий сценарий.
C>Там их больше будет. Например, для возврата объекта в "родной" пул и т.п.
Нет, ибо возвращает их в родные пенаты родной поток. Ну или если родной поток уже помер то вместо добавления в deferred освобождающий поток ограничивается декрементом счётчика выделенных блоков и если достигли нуля — убивает abandoned пул.

C>Получается очень и очень непростой дизайн аллокатора.

C'mon! Нет там ничего сверхсложного. Подумать надо, но никаких сверхнапрягов.
ThreadPoolAlloc у меня занял когда-то около часу ковыряшек из принципа на спор с кем то из шарпников по поводу скорости их GC.

C>>>С -XX:+UseParallelGC.

CC>>Тогда я имею полное право использовать ThreadPoolAlloc. Так что всё равно нету 10х.
C>Так я ведь задизайню тест, где у тебя всё будет сливать моему
Если будет эквивалентный код на Java и С++ — можем попробовать, если тебе ещё не надоело.
Я ведь тоже могу задизайнить тест, где учту слабые стороны GC.

C>Неа. Ты ну никак не можешь сделать многопоточный аллокатор без блокировок (sleeping mutexes) и/или атомарных операций.

Мутексы можно выкинуть вообще, а атомарники нужны только в случае если выделенный объект надо убивать в другом потоке. Если потоки памятью не обмениваются то вообще ничего не надо.
Ну, у ОС память для пулов запрашивать придётся через её API, который сам по себе всегда на блокировке.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 11:37
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>>>Тоже можно Издержки разные, на порядок по времени например только из за медленной компиляции.

N_>>Это решается установкой разработчику нормального компа На современных четырехядерниках даже большие проекты компилятся довольно быстро.
I>5 минут — это чудовищно много.

I>Кроме того, для джавы и дотнета очень много самых различных тулов в силу синтаксиса.

Эту старую песню мы уже слышали.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[29]: Внимание, Java!
От: Cyberax Марс  
Дата: 20.07.10 11:42
Оценка:
Здравствуйте, CreatorCray, Вы писали:

C>>Там их больше будет. Например, для возврата объекта в "родной" пул и т.п.

CC>Нет, ибо возвращает их в родные пенаты родной поток. Ну или если родной поток уже помер то вместо добавления в deferred освобождающий поток ограничивается декрементом счётчика выделенных блоков и если достигли нуля — убивает abandoned пул.
Память на висящий пул теряем, кстати.

C>>Получается очень и очень непростой дизайн аллокатора.

CC>C'mon! Нет там ничего сверхсложного. Подумать надо, но никаких сверхнапрягов.
CC>ThreadPoolAlloc у меня занял когда-то около часу ковыряшек из принципа на спор с кем то из шарпников по поводу скорости их GC.
Это он у тебя ещё маленький.

C>>Так я ведь задизайню тест, где у тебя всё будет сливать моему

CC>Если будет эквивалентный код на Java и С++ — можем попробовать, если тебе ещё не надоело.
CC>Я ведь тоже могу задизайнить тест, где учту слабые стороны GC.
Давай

C>>Неа. Ты ну никак не можешь сделать многопоточный аллокатор без блокировок (sleeping mutexes) и/или атомарных операций.

CC>Мутексы можно выкинуть вообще, а атомарники нужны только в случае если выделенный объект надо убивать в другом потоке. Если потоки памятью не обмениваются то вообще ничего не надо.
Неа. Получается наааамного сложнее. Если ты из другого потока освобождаешь объект, то тебе его надо положить обратно в пул предидущего треда. Начинаются разборки: а как это делать? Тебе надо как-то менять структуры другого потока, причём они при этом могут рейсить с самими операциями потока. Так что надо городить сложный RCU, как минимум.

Либо объекты из других потоков помещать в lookaside-списки, который интегрировать периодически обратно в пул. Но если эти списки растут слишком быстро, то упс.

Ещё можно помещать объект в cleanup-список в текущем потоке (оставляя пометку в заголовке аллокации), откуда его потом читает родительский поток.

Ни один из вариантов не оптимален на 100%. В Hoard'е используется дикая смесь всего этого, но всё равно у них тоже узкие места есть.
Sapienti sat!
Re[30]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 12:23
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>Там их больше будет. Например, для возврата объекта в "родной" пул и т.п.

CC>>Нет, ибо возвращает их в родные пенаты родной поток. Ну или если родной поток уже помер то вместо добавления в deferred освобождающий поток ограничивается декрементом счётчика выделенных блоков и если достигли нуля — убивает abandoned пул.
C>Память на висящий пул теряем, кстати.
Не теряем, она висит занятая, да. И если очень хочется, то можно сделать так, что первый освобождающий в этом пуле забирает его и объединяет со своим пулом.
Я себе такой задачи на момент написания аллокатора не ставил.

C>>>Получается очень и очень непростой дизайн аллокатора.

CC>>C'mon! Нет там ничего сверхсложного. Подумать надо, но никаких сверхнапрягов.
CC>>ThreadPoolAlloc у меня занял когда-то около часу ковыряшек из принципа на спор с кем то из шарпников по поводу скорости их GC.
C>Это он у тебя ещё маленький.
Зато уже шустрый.

C>>>Так я ведь задизайню тест, где у тебя всё будет сливать моему

CC>>Если будет эквивалентный код на Java и С++ — можем попробовать, если тебе ещё не надоело.
CC>>Я ведь тоже могу задизайнить тест, где учту слабые стороны GC.
C>Давай
Так лениво ж. Я ж не ставил себе задачу обгадить жабный GC. Моя задача была показать что С++ может иметь столь же быстрый аллокатор.

C>>>Неа. Ты ну никак не можешь сделать многопоточный аллокатор без блокировок (sleeping mutexes) и/или атомарных операций.

CC>>Мутексы можно выкинуть вообще, а атомарники нужны только в случае если выделенный объект надо убивать в другом потоке. Если потоки памятью не обмениваются то вообще ничего не надо.
C>Неа. Получается наааамного сложнее. Если ты из другого потока освобождаешь объект, то тебе его надо положить обратно в пул предидущего треда. Начинаются разборки: а как это делать? Тебе надо как-то менять структуры другого потока, причём они при этом могут рейсить с самими операциями потока. Так что надо городить сложный RCU, как минимум.
Не намного.

C>Либо объекты из других потоков помещать в lookaside-списки, который интегрировать периодически обратно в пул. Но если эти списки растут слишком быстро, то упс.

C>Ещё можно помещать объект в cleanup-список в текущем потоке (оставляя пометку в заголовке аллокации), откуда его потом читает родительский поток.
Без всяких пометок, просто добавляем освобождаемый в top ISLL, который находится в контексте родительского потока.
Пока из того пула не делаются аллокации нет никакой разницы в free blocks list эти блоки или же в deferred blocks list. А первая же аллокация, которой понадобятся свободные блоки заберёт deferred список и добавит его содержимое в список свободных блоков.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Развязка
От: пыщьх http://rsdn_user.livejournal.com
Дата: 20.07.10 13:08
Оценка: :)
Автор изначального топика разобрался в проблеме и подтвердил, что к C++ она отношения не имеет.

http://www.rsdn.ru/forum/dotnet.web/3885868.1.aspx
Автор: Alex Dav
Дата: 20.07.10

можно сказать и так — оказалась эта гадина при каждом создании объекта еще и в базу лазила
но в любом случае — спасибо за помощью

А какой срач подняли... Как дети малые И, главное, каждый остался при своём
Запретное обсуждение модерирования RSDN:
http://rsdn-user.livejournal.com/652.html
Re[10]: Внимание, Java!
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.07.10 13:11
Оценка: :))
Здравствуйте, CreatorCray, Вы писали:

I>>Кроме того, для джавы и дотнета очень много самых различных тулов в силу синтаксиса.

CC>Эту старую песню мы уже слышали.

Про то и речь — никаких изменений в лучшую сторону нет, остаётся надеяться на железо.
Re[13]: Внимание, Java!
От: Воронков Василий Россия  
Дата: 20.07.10 13:43
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Наиболее прогрессивный вариант — это G1GC ( http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.63.6386&amp;rep=rep1&amp;type=pdf )


Наиболее прогрессивный == более прогрессивный по сравнению с подсчетом ссылок.
Re[31]: Внимание, Java!
От: Cyberax Марс  
Дата: 20.07.10 14:18
Оценка:
Здравствуйте, CreatorCray, Вы писали:

C>>Память на висящий пул теряем, кстати.

CC>Не теряем, она висит занятая, да. И если очень хочется, то можно сделать так, что первый освобождающий в этом пуле забирает его и объединяет со своим пулом.
А дальше начнутся проблемы с cache locality

C>>>>Так я ведь задизайню тест, где у тебя всё будет сливать моему

CC>>>Если будет эквивалентный код на Java и С++ — можем попробовать, если тебе ещё не надоело.
CC>>>Я ведь тоже могу задизайнить тест, где учту слабые стороны GC.
C>>Давай
CC>Так лениво ж. Я ж не ставил себе задачу обгадить жабный GC. Моя задача была показать что С++ может иметь столь же быстрый аллокатор.
Попробую сделать красивый многопоточный тест, с тестированием локальности, lock elision и прочих вкусностей в Java.

C>>Неа. Получается наааамного сложнее. Если ты из другого потока освобождаешь объект, то тебе его надо положить обратно в пул предидущего треда. Начинаются разборки: а как это делать? Тебе надо как-то менять структуры другого потока, причём они при этом могут рейсить с самими операциями потока. Так что надо городить сложный RCU, как минимум.

CC>Не намного.
Ооо....

C>>Либо объекты из других потоков помещать в lookaside-списки, который интегрировать периодически обратно в пул. Но если эти списки растут слишком быстро, то упс.

C>>Ещё можно помещать объект в cleanup-список в текущем потоке (оставляя пометку в заголовке аллокации), откуда его потом читает родительский поток.
CC>Без всяких пометок, просто добавляем освобождаемый в top ISLL, который находится в контексте родительского потока.
CC>Пока из того пула не делаются аллокации нет никакой разницы в free blocks list эти блоки или же в deferred blocks list. А первая же аллокация, которой понадобятся свободные блоки заберёт deferred список и добавит его содержимое в список свободных блоков.
Плохо. Кэш-локальность будет ни к чёрту (в Java она идеальная — выделение из непрерывного блока памяти). Тебе нужно будет объекты раскладывать по bin'ам, кореллирующим с физическим расположением данных.

Я же говорю — много открытий чудных будет. По своему личному опыту говорю
Sapienti sat!
Re[32]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 15:22
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>Память на висящий пул теряем, кстати.

CC>>Не теряем, она висит занятая, да. И если очень хочется, то можно сделать так, что первый освобождающий в этом пуле забирает его и объединяет со своим пулом.
C>А дальше начнутся проблемы с cache locality
С чего бы вдруг. Кончится место в родных chunks будем выделять в забранных.
Page fault count у ThreadPoolAlloc кстати ниже чем у Java с UseParallelGC (11'532 супротив 64'755)

CC>>Так лениво ж. Я ж не ставил себе задачу обгадить жабный GC. Моя задача была показать что С++ может иметь столь же быстрый аллокатор.

C>Попробую сделать красивый многопоточный тест, с тестированием локальности, lock elision и прочих вкусностей в Java.
А потом точно такое же на С++ не забудь. Чтоб можно было сравнить.
У меня есть VTune, который умеет профайлить как Java так и C++. Cache miss показывать умеет.

C>>>Либо объекты из других потоков помещать в lookaside-списки, который интегрировать периодически обратно в пул. Но если эти списки растут слишком быстро, то упс.

C>>>Ещё можно помещать объект в cleanup-список в текущем потоке (оставляя пометку в заголовке аллокации), откуда его потом читает родительский поток.
CC>>Без всяких пометок, просто добавляем освобождаемый в top ISLL, который находится в контексте родительского потока.
CC>>Пока из того пула не делаются аллокации нет никакой разницы в free blocks list эти блоки или же в deferred blocks list. А первая же аллокация, которой понадобятся свободные блоки заберёт deferred список и добавит его содержимое в список свободных блоков.
C>Плохо. Кэш-локальность будет ни к чёрту (в Java она идеальная — выделение из непрерывного блока памяти). Тебе нужно будет объекты раскладывать по bin'ам, кореллирующим с физическим расположением данных.

Java выделяет блоки подряд. Поэтому locality там будет только если одновременно с заполнением контейнера не происходит ещё каких либо долговременных аллокаций. Или жабий GC научился определять какие данные следует положить рядом?
Если дозарезу надо обеспечить locality то мне например проще прицепить к контейнеру специализированный аллокатор, который выделит fixed size objects pool и будет им рулить.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[33]: Внимание, Java!
От: Cyberax Марс  
Дата: 20.07.10 15:26
Оценка:
Здравствуйте, CreatorCray, Вы писали:

C>>А дальше начнутся проблемы с cache locality

CC>С чего бы вдруг. Кончится место в родных chunks будем выделять в забранных.
Вот именно из-за этого. Разные потоки изначально будут иметь разные арены (thread-local пулы), и в кэше каждого потока будут лежать данные по большей части именно из локальной арены.

CC>Page fault count у ThreadPoolAlloc кстати ниже чем у Java с UseParallelGC (11'532 супротив 64'755)

Page fault'ы там возникают в треде с GC, когда он ставит ловушки.

CC>>>Так лениво ж. Я ж не ставил себе задачу обгадить жабный GC. Моя задача была показать что С++ может иметь столь же быстрый аллокатор.

C>>Попробую сделать красивый многопоточный тест, с тестированием локальности, lock elision и прочих вкусностей в Java.
CC>А потом точно такое же на С++ не забудь. Чтоб можно было сравнить.
Это понятно.

CC>У меня есть VTune, который умеет профайлить как Java так и C++. Cache miss показывать умеет.

В Java надо аккуратно только это делать.

C>>Плохо. Кэш-локальность будет ни к чёрту (в Java она идеальная — выделение из непрерывного блока памяти). Тебе нужно будет объекты раскладывать по bin'ам, кореллирующим с физическим расположением данных.

CC>Java выделяет блоки подряд. Поэтому locality там будет только если одновременно с заполнением контейнера не происходит ещё каких либо долговременных аллокаций.
И что? Данные в одном потоке всё равно будут обычно лежать близко.

CC>Если дозарезу надо обеспечить locality то мне например проще прицепить к контейнеру специализированный аллокатор, который выделит fixed size objects pool и будет им рулить.

И попадание на синхронизацию.
Sapienti sat!
Re[34]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 18:57
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>А дальше начнутся проблемы с cache locality

CC>>С чего бы вдруг. Кончится место в родных chunks будем выделять в забранных.
C>Вот именно из-за этого. Разные потоки изначально будут иметь разные арены (thread-local пулы), и в кэше каждого потока будут лежать данные по большей части именно из локальной арены.
1) У потока нет кэша У х86 кэш он или на ядро проца или общий на проц. Потоков же может крутиться сколько угодно.
2) Присоединять чужой пул к своему можно только в случае если поток-владелец другого пула уже помер.

CC>>Page fault count у ThreadPoolAlloc кстати ниже чем у Java с UseParallelGC (11'532 супротив 64'755)

C>Page fault'ы там возникают в треде с GC, когда он ставит ловушки.
Ловушки он ставит для COMMIT следующей страницы, когда памяти отъето больше чем закоммичено.

CC>>У меня есть VTune, который умеет профайлить как Java так и C++. Cache miss показывать умеет.

C>В Java надо аккуратно только это делать.
Читай: в идеальном environment

C>>>Плохо. Кэш-локальность будет ни к чёрту (в Java она идеальная — выделение из непрерывного блока памяти). Тебе нужно будет объекты раскладывать по bin'ам, кореллирующим с физическим расположением данных.

CC>>Java выделяет блоки подряд. Поэтому locality там будет только если одновременно с заполнением контейнера не происходит ещё каких либо долговременных аллокаций.
C>И что? Данные в одном потоке всё равно будут обычно лежать близко.
Зависит. Если расстояние больше чем размер одной линии кэша то locality в жопе.

CC>>Если дозарезу надо обеспечить locality то мне например проще прицепить к контейнеру специализированный аллокатор, который выделит fixed size objects pool и будет им рулить.

C>И попадание на синхронизацию.
Я так понимаю ты себе совсем не представляешь возможность существования аллокатора без обязательной синхронизации?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[35]: Внимание, Java!
От: Cyberax Марс  
Дата: 20.07.10 19:44
Оценка:
Здравствуйте, CreatorCray, Вы писали:

C>>Вот именно из-за этого. Разные потоки изначально будут иметь разные арены (thread-local пулы), и в кэше каждого потока будут лежать данные по большей части именно из локальной арены.

CC>1) У потока нет кэша У х86 кэш он или на ядро проца или общий на проц. Потоков же может крутиться сколько угодно.
Есть Общий кэш процессора.

CC>2) Присоединять чужой пул к своему можно только в случае если поток-владелец другого пула уже помер.

А освобождённые объекты куда попадут?

CC>>>Page fault count у ThreadPoolAlloc кстати ниже чем у Java с UseParallelGC (11'532 супротив 64'755)

C>>Page fault'ы там возникают в треде с GC, когда он ставит ловушки.
CC>Ловушки он ставит для COMMIT следующей страницы, когда памяти отъето больше чем закоммичено.
Не совсем. Он их использует для того, чтобы глушить потоки.

CC>>>У меня есть VTune, который умеет профайлить как Java так и C++. Cache miss показывать умеет.

C>>В Java надо аккуратно только это делать.
CC>Читай: в идеальном environment
Нет, просто много шума.

C>>И что? Данные в одном потоке всё равно будут обычно лежать близко.

CC>Зависит. Если расстояние больше чем размер одной линии кэша то locality в жопе.
Ну так всё равно вероятность попадание в одну линию намного больше.

CC>>>Если дозарезу надо обеспечить locality то мне например проще прицепить к контейнеру специализированный аллокатор, который выделит fixed size objects pool и будет им рулить.

C>>И попадание на синхронизацию.
CC>Я так понимаю ты себе совсем не представляешь возможность существования аллокатора без обязательной синхронизации?
Неа. Под синхронизацией понимаются interlocked-операци и/или мьтексы/события/семафоры.
Sapienti sat!
Re[36]: Внимание, Java!
От: CreatorCray  
Дата: 20.07.10 21:59
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, CreatorCray, Вы писали:


C>>>Вот именно из-за этого. Разные потоки изначально будут иметь разные арены (thread-local пулы), и в кэше каждого потока будут лежать данные по большей части именно из локальной арены.

CC>>1) У потока нет кэша У х86 кэш он или на ядро проца или общий на проц. Потоков же может крутиться сколько угодно.
C>Есть Общий кэш процессора.
Он никак не связан с потоками ОС.

CC>>2) Присоединять чужой пул к своему можно только в случае если поток-владелец другого пула уже помер.

C>А освобождённые объекты куда попадут?
Что значит освобождённые объекты. На уровне аллокатора нет объектов, есть блоки памяти.
Свободные блоки из присоединяемого пула сидят в списке свободных для этого пула. При объединении их следует присоединить в конец списка свободных блоков основного пула.

CC>>>>Page fault count у ThreadPoolAlloc кстати ниже чем у Java с UseParallelGC (11'532 супротив 64'755)

C>>>Page fault'ы там возникают в треде с GC, когда он ставит ловушки.
CC>>Ловушки он ставит для COMMIT следующей страницы, когда памяти отъето больше чем закоммичено.
C>Не совсем. Он их использует для того, чтобы глушить потоки.
Глушить в смысле останавливать? Неужто все остальные способы не подходят? Этож managed код всё таки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.