Мне нужна помощь для производительности молекулярного моделирования N-тел!! (java-апплет)

Я проделал некоторую работу над своим дипломным проектом и получил несколько молекулярных структур + расчет силы при потенциале Леннарда-Джонса и кулоновском потенциале + межмолекулярная связь (как на картинке)

(http://img17.imageshack.us/img17/3133/simulasyon.png)

Все делается с помощью алгоритма Верле в одном потоке.

Проблема в том, что я использую "таблицу вычислений"-массив для быстрых ответов на x ^ (3.5), x ^ (1.4), (1/x).... потому что очень медленно вычислять с помощью собственных методов java . Массив - время доступа очень велико, поэтому я попробовал методы "unsafe()" и все еще очень медленный (прирост производительности всего 10%).

Пробовал IntBuffer и DoubleBuffer и все равно ничего хорошего.

Программа вычисляет O(n) связи, O(nlog(n)) Леннарда-Джонса (+ дополнительный принцип запрета Паули) и O(nlog(n)) расчет кулоновской силы. Плохая скорость при 1500+ частицах (и 7000+ связей).

Я уже проверил, где находится узкое место в скорости (это Леннард Джонс + Кулон). для расчета одного временного шага при 1500 частицах требуется 4 миллисекунды. Мне нужно, чтобы это было 1 миллисекунда.

Только если бы я мог использовать массивы так же быстро, как и любой другой язык (безопасный или нет).

Также попытался заменить деления умножениями, хэш-картами и списками (такая же производительность с массивами).

Знаете ли вы какой-либо другой способ уменьшить время расчета на временной шаг? Спасибо. Компьютер: одноядерный процессор Intel с тактовой частотой 2,0 ГГц, 1,2 ГБ оперативной памяти, Windows-XP SP-3 и Eclipse Indigo.


person huseyin tugrul buyukisik    schedule 20.06.2012    source источник
comment
Интересный вопрос — я немного изменил его пометку, чтобы повысить ваши шансы привлечь нужных людей. Возможно, вы захотите опубликовать некоторый код, в частности небольшой пример, показывающий (медленную) скорость вычислений и (медленную) скорость массивов, когда вы пытались разобраться в этом.   -  person davidfrancis    schedule 21.06.2012
comment
Разрыв в скорости между современными процессорами и памятью намного больше, чем был 15 лет назад. Вы пытались просто вычислить эти значения вместо использования таблиц поиска?   -  person phs    schedule 21.06.2012
comment
Я уже пробовал одиночные переменные для теста памяти. Одна переменная типа 'final a=...' как минимум в 5-8 раз быстрее. Доступ к одиночным переменным прост и быстр, как и в любом другом языке. Массивы - проблема. Я даже заменил массивы локальными массивами, чтобы получить некоторую скорость, но опять же недостаточно (увеличение на 5%). Я мог бы создать 2 000 000 одиночных переменных, если бы предложения «если» были вычислениями с нулевым временем. Даже тогда на добавление 2 миллионов одиночных переменных ушли бы годы :). Вот пример кода:   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
1) Посмотрите на каждую соседнюю сетку (квадраты) 2) посмотрите на каждую частицу в этих сетках. 3) Distance 'Math.sqrt(vxvx+vyvy))' немного медленный, поэтому я попробовал 'answer_array[(int)(vxvx+vyvy) ]' 4) Получить силу под потенциалами Леннарда-Джонса и Кулона '1.0/distance' медленно, поэтому я использовал 'division_array[(int)distance]', затем 'Math.pow(x,n)' медленный x xx* тоже недостаточно! я использовал 'power_n_array[x]' 5) Рассчитайте силы связей, если есть какие-либо 'f=k*(balance_distance-distance)', даже для этого я использую 'f=k_matrix[(int)(delta_distance)]', это самый быстрый i мог. «Время доступа к массиву» составляет 3 единицы (0,4 единицы для одиночного)   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
для xx нет прироста производительности, но для xxxx прирост производительности за счет выборки элементов массива быстрее (почти %30) (безопасное время доступа к массиву Java).   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
в той же области я использовал Math.pow(1.0/distance,3.5). Это самая медленная версия. Это было для обеих частиц (в 2 раза медленнее). Поэтому я использовал двойную инверсию = 1,0 / расстояние (это было рассчитано только один раз и использовано дважды). И затем я использовал inverseinverseinverse*Math.sqrt(inverse) . Затем я изменил inverse^3 на power_n_array[] и Math.sqrt() на root_array[]. В C я сделал то же самое для моделирования гравитации, и это было хорошо. Я знаю, что это обман, но мне просто нужна скорость больше, чем точность! забыл сказать, что это 2Dimenson   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
Вы усекаете расчеты потенциала Леннарда-Джонса?   -  person High Performance Mark    schedule 21.06.2012
comment
Да, усеченные до 2-го ближайшего соседа частицы ячейки (и радиус) также изменили все двойные числа с поплавками. нет решения.   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
каждая ячейка не больше, чем в 2 раза больше диаметра частицы   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
Расчеты O(nlog(n)) с усечением. избегал всех O (n ^ 2)   -  person huseyin tugrul buyukisik    schedule 21.06.2012
comment
Было бы легче помочь, если бы вы могли разместить код где-нибудь...   -  person Nitsan Wakart    schedule 19.01.2013
comment
пожалуйста, выложите рабочий образец   -  person rpax    schedule 07.04.2014


Ответы (1)


Вместо использования интерполяционных таблиц попробуйте использовать полиномы Чебышева. Помните, что вы можете возвести x^k в степень только за ln(k) шагов.

Может показаться, что это много операций, но тот факт, что их можно выполнить, не затрагивая память (и, следовательно, не затрагивая кеш), может сделать их значительно быстрее, чем таблицы поиска.

person rocketblast    schedule 14.11.2016
comment
Да, сегодня процессор может выполнять вычисления намного быстрее, чем оперативная память. Тоже было слишком давно. Теперь я использую gpgpu, что намного проще, чем оптимизация для конкретного процессора, и я мог бы использовать ваше предложение и в gpgpu. Спасибо. - person huseyin tugrul buyukisik; 14.11.2016