Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

Есть ли на Java православная возможность реализации unsafe кроме JNI вызовов?

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Собственно, требуется возможность быстрой работы с матрицами на java по 20-100 млн элементов. Матрицы загружаются в память. Но safe реализация кода приводит к тому, что обрабатывающий код исполняется до 40 секунд.

Кроме реализации ресурсожрущего кода на С++ и подключение его через JNI ничего в голову не приходит.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
А что собственно узкое место? Какие операции выполняете с матрицами?
1. Может все уходит в своп и тогда вам надо менять стратегию обхода матриц? Может какая-то разреженность все таки возможна в вашем случае?

2. Или вы делаете сложные вычисления на базе этих матриц? И садите процессор? На графическом процессоре работа с матрицами может давать ощутимые преимущества.

Сложные вичисления. Проблема в проверке выхода за границы массива при каждом обращении к элементу массива. Unsafe код на C# работает гораздо быстрее, на С++ еще быстрее.

В общем понял — оптимизация группы алгоритмов или перевод части кода на C++.

PS

На смартфонах вроде нет прямого доступа к вычислениям на GPU?.

Смотри, если у тебя один из последних андроидосмартов с тегрой, то там есть renderscript.На него можно переложить часть задач, он работает непосредственно с GPU, но боюсь там потеряешь при переводе матриц в нужную структуру для вычислений.

Я обсчитывал flow dynamics пару лет назад на CUDA и эта конвертация сильно била по скорости, так что может оказаться сомнительной эта фича..

Альтернатива — memory mapped files, джава их поддерживает через NIO

Я знаю как работает механизм файловой системы Windows, это решение тормознет работу с массивами еще в 10 раз, если для доступа к каждому элементу делать файловый вызов.

Для memory mapped files не нужно делать каждый раз файловый вызов

Hm, why do you need files? Use ByteBuffer.allocateDirect

or sun.misc.Unsafe robaustin.wikidot.com/...cations-in-java

or sun.misc.Unsafe
Уж простите, что я на русском.
Вроде весь пакет sun — не публичный, то есть его использовать не рекомендуется и он может быть в любой момент исключен.
Кстати, я не слышал про его реальное использование в живих проектах. В ЛинкедИне используют? Если да интересно как?
Use ByteBuffer.allocateDirect
А это будет быстрее чем работа с массивом? Если есть ссылки, интересно будет почитать. У ТСа, по его словам, тормозят даже они.
Vazhko pusatu kurulecejy. sun.misc.Unsafe vukorustovyjet’s’a v DirectByteBuffer i java.util.concurrent.atomic classes. Na prjamy napevno ne maje zmisty vukorustovyvatu, ja prosto vidpoviv na putannja topic starter’a stosovno unsafe operacij v pamjati. V LinkedIn vukorustovyjet’s’a DirectByteBuffer, jakuj v svojy 4ergy sun.misc.Unsafe. Vukorustovyjet’s’a dlja togo, sh4ob stvoryvatu objektu za mezhamu Heap i ne tratutu resyrsu na GC.

Stosovno performance, napevne topic startery potribno pokazatu kod. Ja dymajy jogo mozhna optumizyvatu bez JNI

ААААА! Паника)

Пишите на английском. Здесь поймут

Автор как бы писал, но здесь признали за моветон или автор сам смутился :)

Или Google Russian Input. Или Grammatica IME (на правах рекламы)

На практике мерить не приходилось при работе с большими объемами данных, но наверное мы немного можем экономить на том что GC не будет заниматься обработкой этой памяти. Собственно мне нравится набор средств описанный на блоге: www.javaspecialist.ru/...heap-cache.html.

Богдан, sun.misc.Unsafe не использует только ленивый. Одноклассники пишут об этом на Хабре, например (ГСС).

Класс этот есть в JVM много-много лет, он есть также и в JRockit и в IBM JVM. Так что особенных причин бояться его использовать нет. Его уже никто не будет удалять из api, т.к. слишком много кода написано серьезными ребятами с большими залежами легаси-приложений по всему миру с его использованием.

ByteBuffer.allocateDirect не дает выделять память больше чем MAX_INT, что для обычных случаев просто не хватает (матрица 500 на 500 тысяч в обычный массив не влезает).

Вообще, топик-стартеру советую посмотреть, как занимаются вычислениями на Java нормальные люди. Наверняка от Java там только Hadoop, а все джобы для него поставляются в виде тонких врапперов вокруг библиотек на Fortran. Хотя, мб библиотеки там тоже на чистой Java. В общем, гуглите и не велосипедничайте понапрасну.

Ну работу с большими матрицами, научные вычисления и прочее чаще всего пишут либо на FORTRAN, как было уже правильно замечено, либо на с++ с использованием GPU (CUDA, opencl), SIMD etc.

Ну работу с большими матрицами, ... пишут либо на FORTRAN ... либо на с++ с использованием GPU (CUDA, opencl), SIMD etc.

А может вместо того чтобы начать изучать Хаскалл, надо подумать и не грузить все в память если пердполагаетсо что размер данных неограничен.

быстрой работы с матрицами на java по 20-100 млн элементов.

что обрабатывающий код исполняется до 40 секунд.

Предсказание: проблема или в коде или в настройкам ДжВМ (мало памяти).

Но safe реализация кода приводит к тому,

Код вы вряд ли покажете. Трассы профайлера хоть. Что там светится?

Предсказание: проблема или в коде или в настройкам ДжВМ (мало памяти).

В коде проблем нет, просто там идет работа с большими окнами по 11^2 элементов на пиксел (элемент). В общем адаптивная бинаризация 600dpi-ных изображений.

В коде проблем нет
Ну на это я могу Вам сказать, что в джвм проблем с вычислениями в памяти тоже нет проблем...

Можно, вопрос в том — поможет ли это? Было бы не плохо видеть код, очень вероятно проблема только в самом коде.

Возможно проблема таки не в коде. Есть языки и компилеры которые легко векторизируют матричные операции(фортран,цпп), а есть которые похуже.

В любом случае для джавы есть вроде байндинг к LAPAC, так что в худшем случае можно его заюзать.

Возможно проблема таки не в коде.
Не знаю, не знаю... Я еще не встречался с проблемой, когда узкое место в джвме или компиляторе.

Я еще не встречался с проблемой, когда узкое место в джвме или компиляторе.

1) Числодробилки: именно много операций с плавающей точкой. Тут ЦПП довольно часто выносит Джаву (по моему субъективному опыту)

2) Операции с многомерными массивами. Но тут ближе таки к коду: их надо правильно переворачивать.

Как я уже написал проблема в векторизации. Типа если у тебя есть цикл for(...) a[i] += b[i]; компиллер может умещать несколько сложений в одну векторизированную команду. Это если компиллер умный и знает что масивы a и b не пересекаются. Практика показывает что джава компилеры недостаточно умны в этом направлении по сравнению с c++/fortran компилерами. Второй момент что джава может делать index out of bound чек на каждой итерации и это тоже сильно тормозит цикл.

Джава компилеры достаточно умны, а горячий код еще и дополнительно оптимизируется.

Index out of bound также может отсутствовать, но это зависит...

Но матричные либы на джаве почемы то в разы стабильно проигрывают ц+±ным

Ммм, попытался нагуглить — не нашел. Было бы интересно взглянуть на пруфы.

Ни и где же там пруфы? Вы читали? Там как раз говорится, что скорость зависит от конкретных либ и от конкретной задачи.

Там говорится что на всех приведенных задачах все конкретные джава либы сливают всем конкретным ц++/fortran либам. Других случаев я там не заметил.

Возможно проблема таки не в коде.
ИМХО, таки в коде, ибо даже если:
Есть языки и компилеры которые легко векторизируют матричные операции(фортран,цпп), а есть которые похуже.
то фраза:
по 20-100 млн элементов
наводит на мысль что надо думать перед тем как грузить всякую хну в память.

Но важно другое:
Судя по всему человек даже не запускал профайлер, так шо наши гадания бессмысленны.

А теперь самое важное:

В любом случае для джавы есть вроде байндинг к LAPAC
Что такое LAPAC? Для чего оно надо? И ссылочки «на почитать».
по 20-100 млн элементов

наводит на мысль что надо думать перед тем как грузить всякую хну в память.

100 млн чисел это 1 гб, в чем проблема с грузить в память?

Что такое LAPAC? Для чего оно надо? И ссылочки «на почитать».

www.netlib.org/lapack

100 млн чисел это 1 гб, в чем проблема с грузить в память?

Дело не столько в объеме, сколько в количестве и в том что оно очень просто растет. Да и 1Гб — это не так уж и мало.

В данном случае это скорее всего не фактор.

Можно ещё так: www.docjar.com/...nsafe.java.html

Судя по вопросу, Вам нужна возможность выделять/очищать память вручную (без GC).

Он в пакете sun, то есть не публичное и может пропасть в любой момент.

Про это знаю, но это больше похоже на хак.

Вызывать нативный код можно через JNA, SWIG еще.
Можно еще по профайлить и пооптимизировать твой дхавовский код, уверен там есть косяки.

Есть куча джавовских либ по работе с матрицами, можно попробовать заюзать их или поискать в них вдохновения на тему оптимизации

Підписатись на коментарі