tag:blogger.com,1999:blog-410416665291724878.post1939514660058946250..comments2022-12-19T13:52:22.907+04:00Comments on >рабочие заметки: Without locksRuslan Chereminhttp://www.blogger.com/profile/01023948540752159657noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-410416665291724878.post-57123877306928365632011-06-02T13:41:08.604+04:002011-06-02T13:41:08.604+04:00Быстрее volatile-флажка не придумаешь, по-моему.
...Быстрее volatile-флажка не придумаешь, по-моему. <br /><br />Хорошо, если gap между окончаниями потоков маленький. В общем случае этого гарантировать нельзя, конечно, поэтому проще озаботиться правильной схемой остановки с BOGUS в конце. Например, следующим заходом сделаете в каждой итерации тысячупятьсот get()'ов из кеша, время одной итерации подскочит до нескольких секунд, и тут-то ваша Aleksey Shipilev:https://www.blogger.com/profile/01270446535942765702noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-92231149366721960682011-06-02T13:33:56.659+04:002011-06-02T13:33:56.659+04:00>Мы обычно поступаем проще: минимизируем расход...>Мы обычно поступаем проще: минимизируем расходы на инфраструктуру сразу.<br /><br />На самом деле я пока не придумал, как можно еще больше минимизировать расходы на инфраструктуру. Там, вроде бы, для "измерительных" итераций, всего одно волатильное чтение на итерацию. Мне показалось это достаточным -- не могу придумать, как можно подать одновременный сигнал всем потокам на Ruslan Chereminhttps://www.blogger.com/profile/01023948540752159657noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-3235808261098754792011-06-02T13:24:45.957+04:002011-06-02T13:24:45.957+04:00А, ну если вы померили baseline с пустым кешем, и ...А, ну если вы померили baseline с пустым кешем, и отнимаете значение этого baseline'а из всех остальных измерений, и только потом считаете проценты -- то нормально, да :) Мы обычно поступаем проще: минимизируем расходы на инфраструктуру сразу.<br /><br />В конце BOGUS-итерации надо считать потому, что если некоторые потоки завершатся раньше, всем остальным будет проще считать: и хардварных Aleksey Shipilev:https://www.blogger.com/profile/01270446535942765702noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-7783040625049164302011-06-02T13:14:38.762+04:002011-06-02T13:14:38.762+04:00Спасибо за комплимент :) Я старался.
>Добавить...Спасибо за комплимент :) Я старался.<br /><br />>Добавить бы в микробенчмарк калибровку количества итераций<br /><br />Там же есть опция "empty" когда вместо кэша подставляется NoCache(identity()), что, по моему разумению, должно просто инлайниться в пустое место. Я ее и использую для калибровки -- с ней "производительность" примерно в 2-3 раза выше, чем лучшие результаты Ruslan Chereminhttps://www.blogger.com/profile/01023948540752159657noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-59753010113096976322011-06-02T13:01:31.006+04:002011-06-02T13:01:31.006+04:00Ну, я прямо вами горжусь. :) Наконец-то кто-то пиш...Ну, я прямо вами горжусь. :) Наконец-то кто-то пишет микробенчмарки, от которых не тошнит.<br /><br />Добавить бы в микробенчмарк калибровку количества итераций, а то получается, что вы делаете loop{key = generator.nextValue -> lru.key.equals(key) -> return lru -> afterEachIteration()}, а потому можете случайно мерить не столько скорость самого быстрого случая в кеше, сколько скорость Aleksey Shipilev:https://www.blogger.com/profile/01270446535942765702noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-6267458781610970242011-06-01T21:31:41.234+04:002011-06-01T21:31:41.234+04:00...зато мои последние микробенчмарки дают для стац......зато мои последние микробенчмарки дают для стационарного режима (когда все актуальные ключи уже вычислены и закэшированы) примерно 70-100% прироста скорости чтения из кэша по сравнению с кэшем на базе ConcurrentHashMap (я использовал реализацию из google-guava). Я пока в фоновом режиме играюсь с различными параметрами бенчмарка -- но если эти цифры подтвердятся, то игра стоит свеч :)<br /><br Ruslan Chereminhttps://www.blogger.com/profile/01023948540752159657noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-65020651257483674282011-06-01T20:05:44.840+04:002011-06-01T20:05:44.840+04:00>Строго говоря, неявные scalability bottleneck&...>Строго говоря, неявные scalability bottleneck'и будут<br /><br />Да, это конечно правда. Но это очень упрощенный пример. Он хорошо будет работать, если априори известно, что вообще-то функция 99.9 вызывается с одним и тем же аргументом (я в таких случаях эту штуку и использую). Если расширить реализацию для хранения массива значений (в духе fixed-size hash map) -- опять же, вероятность Ruslan Chereminhttps://www.blogger.com/profile/01023948540752159657noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-38692667292958338862011-05-23T13:11:02.577+04:002011-05-23T13:11:02.577+04:00А, и кстати, в коде -- гарантированный NPE на втор...А, и кстати, в коде -- гарантированный NPE на втором же вызове get(null).Aleksey Shipilev:https://www.blogger.com/profile/01270446535942765702noreply@blogger.comtag:blogger.com,1999:blog-410416665291724878.post-47458168859368650132011-05-23T13:06:18.678+04:002011-05-23T13:06:18.678+04:00Строго говоря, неявные scalability bottleneck'...Строго говоря, неявные scalability bottleneck'и будут, ибо поле recentUsed будет пользоваться несколькими тредами, а значит, хардварные кеши всё равно будут бешено пытаться это значение синхронизировать. А поскольку в плохом случае запись будет производиться на каждый get(), то в патологическом случае с производительностью можно попрощаться. <br /><br />Я бы сделал либо вероятностную запись (Aleksey Shipilev:https://www.blogger.com/profile/01270446535942765702noreply@blogger.com