Java: 32-битная реализация Math.sqrt () для fp

Стандартный метод Math.sqrt() в Java кажется довольно быстрым, но у него есть свойственный недостаток: он всегда будет включать 64- битовые операции, которые только уменьшают скорость при работе с 32-битными значениями float. Можно ли добиться большего успеха с помощью пользовательского метода, который использует float в качестве параметра, выполняет только 32-разрядные операции и возвращает ---- +: = 3 =: + ---- в результате?

Я видел:

Быстрый sqrt в Java за счет точности

и это лишь немного укрепило представление о том, что Math.sqrt () обычно трудно победить. Я также видел:

http: //www.codeproject .com /Статьи /69941 /Best-Square-Root-метод-алгоритм-Function-Precisi

, который показал мне кучу интересных взломов C ++ /ASM, которые я просто слишком невежествен, чтобы портировать прямо на Java. Хотя sqrt14 может быть интересным как часть вызова JNI. , .

Я также посмотрел на Apache Commons FastMath, но похоже, что эта библиотека по умолчанию соответствует стандартному Math.sqrt (), так что тут никакой помощи. И еще есть Yeppp!:

http://www.yeppp.info/

но я еще не беспокоился об этом.

7 голосов | спросил user3765373 11 J0000006Europe/Moscow 2015, 11:53:21

2 ответа


0

Вам не нужно ничего ускорять sqrt для 32-битных значений. HotSpot JVM делает это автоматически для вас.

JIT-компилятор достаточно умен, чтобы распознавать шаблон f2d -> Math.sqrt() -> d2f и заменять его более быстрым sqrtss Инструкция процессора вместо sqrtsd. источник .

Тест:

@State(Scope.Benchmark)
public class Sqrt {
    double d = Math.random();
    float f = (float) d;

    @Benchmark
    public double sqrtD() {
        return Math.sqrt(d);
    }

    @Benchmark
    public float sqrtF() {
        return (float) Math.sqrt(f);
    }
}

И результаты:

Benchmark    Mode  Cnt       Score      Error   Units
Sqrt.sqrtD  thrpt    5  145501,072 ± 2211,666  ops/ms
Sqrt.sqrtF  thrpt    5  223657,110 ± 2268,735  ops/ms
ответил apangin 11 J0000006Europe/Moscow 2015, 13:34:12
0

Как вы, кажется, знаете JNI:

просто напишите минимальную оболочку для double sqrt(double) и float sqrt(float) из стандартной библиотеки C math.h и сравните производительность.

Подсказка: вы не почувствуете разницы, если не будете много квадратного корня, и тогда преимущество в производительности, скорее всего, будет заключаться в преимуществах использования инструкций SIMD для одновременного выполнения нескольких sqrts Вам нужно будет получить выровненный по памяти массив значений с плавающей точкой из Java, что может быть довольно сложно, если вы используете стандартные библиотеки Java.

ответил Marcus Müller 11 J0000006Europe/Moscow 2015, 12:13:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132