31 июля 2009 г.
Наконец-то раскочегарились работы по физконструктору. Изучаю физику заново -- ощущение, что забыл все. Точнее, саму физику на качественном уровне я еще помню, но вот выписывать уравнения я напрочь разучился. Сижу туплю по полчаса над школьными уравнениями движения. Решение задачи о столкновении шаров заняло часа три и вызвало бурю радости :)
16 июля 2009 г.
Float vs Double
Тестировал производительность плавающей запятой в java. Обычно я везде использую double, но пока изучал jbullet заметил, что там вся арифметика на float-ах, и мне стало интересно.
тестировал под 1.6.0_14, с опциями -server -XX:+DoEscapeAnalysis -Xmx300m -Xms300m
В итоге, получается, что сложение/умножение примерно в два раза медленнее для double, деление -- примерно на 30%, сравнение мало отличается. Буду теперь для операций, не требующих особой точности, активно использовать float.
- import junit.framework.TestCase;
-
- public class FloatVsDoublePerfomance extends TestCase {
- private static final int[] SIZES = new int[]{ 1000, 10000, 100000, 300000 };
- private static final int ITER = 10000;
-
- public void test() {
- for ( int i = 0; i < SIZES.length; i++ ) {
- final int size = SIZES[i];
-
- _testFloat( size );
- System.gc();
- System.gc();
-
- _testDouble( size );
- System.gc();
- System.gc();
- }
- }
-
- private static void _testFloat( final int size ) {
- final float[] arr = createFloatArray( size );
-
- System.out.printf( "float[%d * %d]\n", size, ITER );
- //warm-up -- cache load, etc
- testFloatCompare( arr );
-
-
- long startedAt = System.currentTimeMillis();
- //compare
- for ( int i = 0; i < ITER; i++ ) {
- testFloatCompare( arr );
- }
- System.out.printf( "\tcompare: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //summ
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testFloatSumm( arr );
- }
- System.out.printf( "\tsum: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //mul
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testFloatMul( arr );
- }
- System.out.printf( "\tmul: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //div
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testFloatDiv( arr );
- }
- System.out.printf( "\tdiv: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
- }
-
- private static void _testDouble( final int size ) {
- final double[] arr = createDoubleArray( size );
-
- System.out.printf( "double[%d * %d]\n", size, ITER );
- //warm-up -- cache load, etc
- testDoubleCompare( arr );
-
-
- long startedAt = System.currentTimeMillis();
- //compare
- for ( int i = 0; i < ITER; i++ ) {
- testDoubleCompare( arr );
- }
- System.out.printf( "\tcompare: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //summ
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testDoubleSumm( arr );
- }
- System.out.printf( "\tsum: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //mul
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testDoubleMul( arr );
- }
- System.out.printf( "\tmul: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
-
- //div
- startedAt = System.currentTimeMillis();
- for ( int i = 0; i < ITER; i++ ) {
- testDoubleDiv( arr );
- }
- System.out.printf( "\tdiv: %d ms\n", ( System.currentTimeMillis() - startedAt ) );
- }
-
- private static float[] createFloatArray( final int size ) {
- final float[] arr = new float[size];
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = ( float )( Math.random() * 100 );
- }
- return arr;
- }
-
- private static void testFloatDiv( final float[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] / arr[i];
- }
- }
-
- private static void testFloatMul( final float[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] * arr[i];
- }
- }
-
- private static void testFloatSumm( final float[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] + arr[i];
- }
- }
-
- private static void testFloatCompare( final float[] arr ) {
- int _ = 0;
- for ( int i = 0; i < arr.length; i++ ) {
- if ( arr[i] < 50 ) {
- _++;//просто чтобы компилятор не выкинул сравнение
- }
- }
- }
-
-
- private static double[] createDoubleArray( final int size ) {
- final double[] arr = new double[size];
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = Math.random() * 100;
- }
- return arr;
- }
-
- private static void testDoubleDiv( final double[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] / arr[i];
- }
- }
-
- private static void testDoubleMul( final double[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] * arr[i];
- }
- }
-
- private static void testDoubleSumm( final double[] arr ) {
- for ( int i = 0; i < arr.length; i++ ) {
- arr[i] = arr[i] + arr[i];
- }
- }
-
- private static void testDoubleCompare( final double[] arr ) {
- int _ = 0;
- for ( int i = 0; i < arr.length; i++ ) {
- if ( arr[i] < 50 ) {
- _++;//просто чтобы компилятор не выкинул сравнение
- }
- }
- }
- }
* This source code was highlighted with Source Code Highlighter.
тестировал под 1.6.0_14, с опциями -server -XX:+DoEscapeAnalysis -Xmx300m -Xms300m
В итоге, получается, что сложение/умножение примерно в два раза медленнее для double, деление -- примерно на 30%, сравнение мало отличается. Буду теперь для операций, не требующих особой точности, активно использовать float.
Ярлыки:
рабочее,
физконструктор,
benchmarking,
floating point
15 июля 2009 г.
Последнее время занят активным изучением физических движков -- на джаве и не только. Основная сложность в том, что задачи, которые решаем мы, нетипичны, ими мало кто занимается.
Например: есть множество движков игровой физики -- часть из них даже бесплатна, и портирована на джаву (JBullet, ODE4j). Но они заточены под максимально быструю симуляцию физики -- т.е. система должна выглядеть похоже на реальную. Основные задачи, которые они решают -- движение большого количества тел в простых силовых полях (чаще всего в равномерном поле тяжести), расчет столкновений, учет связей, диссипация. Самое сложное там -- как раз быстрый расчет столкновений и взаимопроникновений тел, связи и силы реакции. Все остальное делается по остаточному принципу -- как правило используется простейшая интеграционная схема Эйлера, которая, вообще говоря, расходится по энергии, но в присутствии трения становится более-менее стабильной, зато обеспечивает завидную скорость расчета. Демки JBullet, где в real-time просчитываются (и рендерятся!) до полусотни объектов довольно сложной геометрии (на java!) впечатляют. При этом попытка смоделировать идеальный биллиард (без диссипации) на этом движке проваливается -- схема эйлера "взрывается" уже через пару минут симуляции.
С другой стороны находятся чисто научные движки. Но они, как правило, заточены под моделирование какой-то конкретной системы. Т.е. программа с их использованием пишется для решения конкретной задачи или класса задач. Кроме того о real-time речь обычно не идет. Да и на джаву они не портированы -- джава, все-таки, пока еще не особо котируется в high perfomance computing
Нам же нужен движок во-первых универсальный -- т.е. единообразно моделировать большинство задач механики, просто накидал объектов и взаимодействий, и сказал "поехали!" -- и он сам со всем разобрался. Во-вторых, с производительностью, близкой к реальному времени для расчета хотя бы десятка сложных объектов, или до сотни простых (моделировать молекулярную механику -- чем больше, тем лучше). Нужно моделировать всяческие идеализации, используемые в механике: идеальные связи (нерастяжимые невесомые стержни, нити, блоки, цепи), идеальные столкновения. Причем все это должно моделироваться максимально "физически" -- т.е. с как можно лучшим сохранением основных инвариантов уравнений движения (энергии, импульса, момента импульса, и т.п.) на временах моделирования хотя бы порядка 10 минут. Такого пока нигде не видел.
Прикидываю, как буду писать сам.
Например: есть множество движков игровой физики -- часть из них даже бесплатна, и портирована на джаву (JBullet, ODE4j). Но они заточены под максимально быструю симуляцию физики -- т.е. система должна выглядеть похоже на реальную. Основные задачи, которые они решают -- движение большого количества тел в простых силовых полях (чаще всего в равномерном поле тяжести), расчет столкновений, учет связей, диссипация. Самое сложное там -- как раз быстрый расчет столкновений и взаимопроникновений тел, связи и силы реакции. Все остальное делается по остаточному принципу -- как правило используется простейшая интеграционная схема Эйлера, которая, вообще говоря, расходится по энергии, но в присутствии трения становится более-менее стабильной, зато обеспечивает завидную скорость расчета. Демки JBullet, где в real-time просчитываются (и рендерятся!) до полусотни объектов довольно сложной геометрии (на java!) впечатляют. При этом попытка смоделировать идеальный биллиард (без диссипации) на этом движке проваливается -- схема эйлера "взрывается" уже через пару минут симуляции.
С другой стороны находятся чисто научные движки. Но они, как правило, заточены под моделирование какой-то конкретной системы. Т.е. программа с их использованием пишется для решения конкретной задачи или класса задач. Кроме того о real-time речь обычно не идет. Да и на джаву они не портированы -- джава, все-таки, пока еще не особо котируется в high perfomance computing
Нам же нужен движок во-первых универсальный -- т.е. единообразно моделировать большинство задач механики, просто накидал объектов и взаимодействий, и сказал "поехали!" -- и он сам со всем разобрался. Во-вторых, с производительностью, близкой к реальному времени для расчета хотя бы десятка сложных объектов, или до сотни простых (моделировать молекулярную механику -- чем больше, тем лучше). Нужно моделировать всяческие идеализации, используемые в механике: идеальные связи (нерастяжимые невесомые стержни, нити, блоки, цепи), идеальные столкновения. Причем все это должно моделироваться максимально "физически" -- т.е. с как можно лучшим сохранением основных инвариантов уравнений движения (энергии, импульса, момента импульса, и т.п.) на временах моделирования хотя бы порядка 10 минут. Такого пока нигде не видел.
Прикидываю, как буду писать сам.
Подписаться на:
Сообщения (Atom)