Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 17

Тема: int_sqrt

  1. #1
    Аватар для SooBad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.04.2017
    Адрес
    Краснодар
    Сообщений
    83
    Репутация:
    20 ±

    int_sqrt

    Название: int_sqrt

    Нотация: самописная функция, предназначенная для вычисления корня у значений целочисленного типа. Аналог нативного floatsqroot и си-шного sqrt.

    Производительность: при 10k итераций тесты возвращают результат, равный 0-2 ms.

    Плюсы реализации:
    • При написании независимых систем вам не придётся подгружать библиотеку float для подсчётов, с применением лишь одной функции.
    • Не требует преобразований целочисленных значений в вещественные, в отличие от того же floatsqroot.

    Минусы реализации: думаю, что объяснять причины отсутствия поддержки функцией значений вещественного типа - не нужно.

    Пример использования(работоспособность):
    PHP код:
    main()
    {
        new
            
    test_value 250;

        
    printf("%d"int_sqrt(test_value 5));

        
    //result = 15

    Исходный код:
    PHP код:
    stock int_sqrt(value)
    {
        new
            
    result,
            
    temp,
            
    degr_count;

        for(new 
    3>= 0i--)
        {
            
    temp degr_count |= 0b11 << (0b10 i) & value;

            
    returning:
            
    result ^= 0b1 << i;

            if(
    temp < (result result))
                goto 
    returning;
        }
        return 
    result;

    Автор: SooBad.
    Последний раз редактировалось SooBad; 05.05.2017 в 17:54.

  2. Пользователь сказал cпасибо:
    DeimoS (01.05.2017)
  3. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от SooBad Посмотреть сообщение
    • При написании независимых систем вам не придётся подгружать библиотеку float для подсчётов, с применением лишь одной функции.
    Так можно ведь просто прописать саму нативку для floatsqroot, а не грузить всю библиотеку, которая, тащемта, из одних нативок, в основном, и состоит :)


    Цитата Сообщение от SooBad Посмотреть сообщение
    P.S. Что за проблемы с табуляцией?
    Скорее всего просто табы перемешаны с пробелами были. В редакторах это не заметно, а вот на форумах разница видна.
    Это проблема не только данного форума, если что
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  4. #3
    Аватар для SooBad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.04.2017
    Адрес
    Краснодар
    Сообщений
    83
    Репутация:
    20 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Так можно ведь просто прописать саму нативку для floatsqroot, а не грузить всю библиотеку, которая, тащемта, из одних нативок, в основном, и состоит :)
    Да, можно. Я уже по ходу реализации об этом подумал.
    Но, плюсы от функции всё равно определенные есть. Насколько я знаю, когда мы в floatsqroot, да и в других float-функциях работаем с целыми числами, то компилятор выплевывает предупреждение о потере тега. Проверить сейчас это нет возможности.


    Цитата Сообщение от DeimoS Посмотреть сообщение
    Скорее всего просто табы перемешаны с пробелами были. В редакторах это не заметно, а вот на форумах разница видна.
    Да, скорее всего, так и есть.

  5. #4
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от SooBad Посмотреть сообщение
    Производительность: при 10k итераций тесты возвращают результат, равный 0-2 ms.
    Объективнее сравнивать с чем-либо, потому что мощности железа у каждого разные и замеры одной функции на одной машине вряд ли кому-то дадут конкретную информацию.

    А так, хорошо бы ещё было увидеть как раз библиотеку с аналогами из float.inc, но для целочисленных переменных, вроде abs(olute), power, log(arithm) и т.д.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  6. Пользователь сказал cпасибо:
    SooBad (01.05.2017)
  7. #5
    Аватар для SooBad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.04.2017
    Адрес
    Краснодар
    Сообщений
    83
    Репутация:
    20 ±
    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    Объективнее сравнивать с чем-либо, потому что мощности железа у каждого разные и замеры одной функции на одной машине вряд ли кому-то дадут конкретную информацию.
    Сравнения происходили с аналоговым нативом. При 10k был возвращен тиковый результат, колеблющийся от 0 до 2 млс.
    При 100k значения незначительно, но стали разниться, в пользу натива. 3 против 13. Тестировать на больших количествах итераций - смысла не вижу. Разницы, фактически, никакой.

    Цитата Сообщение от Nexius_Tailer Посмотреть сообщение
    А так, хорошо бы ещё было увидеть как раз библиотеку с аналогами из float.inc, но для целочисленных переменных, вроде abs(olute), power, log(arithm) и т.д.
    Хорошая идея. Думаю, в ближайшем времени, реализую.

  8. #6
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    PHP код:
            degr_count |= 0b11 << (0b10 i);
            
            
    #emit load.s.pri value
            #emit load.s.alt degr_count
            #emit and
            #emit stor.s.pri temp
            
            
    returning:
            
    result ^= 0b1 << i
    В чём профит использовать #emit таким образом? Компилятор и без этого сгенерирует точно такую же последовательность инструкций.
    PHP код:
    main()
    {
        new 
    abc;
        
    b;
        
    #pragma unused c

    Код:
    	proc	; main
    	; line 6
    	; line 7
    	;$lcl a fffffffc
    	push.c 0
    	;$exp
    	;$lcl b fffffff8
    	push.c 0
    	;$exp
    	;$lcl c fffffff4
    	push.c 0
    	;$exp
    	; line 8
    
    	load.s.pri fffffff8
    	load.s.alt fffffffc
    	and
    	stor.s.pri fffffff4
    
    	;$exp
    	stack c
    	zero.pri
    	retn
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #7
    Аватар для SooBad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.04.2017
    Адрес
    Краснодар
    Сообщений
    83
    Репутация:
    20 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В чём профит использовать #emit таким образом? Компилятор и без этого сгенерирует точно такую же последовательность инструкций.
    PHP код:
    main()
    {
        new 
    abc;
        
    b;
        
    #pragma unused c

    Код:
    	proc	; main
    	; line 6
    	; line 7
    	;$lcl a fffffffc
    	push.c 0
    	;$exp
    	;$lcl b fffffff8
    	push.c 0
    	;$exp
    	;$lcl c fffffff4
    	push.c 0
    	;$exp
    	; line 8
    
    	load.s.pri fffffff8
    	load.s.alt fffffffc
    	and
    	stor.s.pri fffffff4
    
    	;$exp
    	stack c
    	zero.pri
    	retn
    Да, разницы никакой нет. Это вполне очевидно.
    Всё упирается лишь в восприятие кода и совместимости. (Некоторые не знают про данный оператор, либо используют pawn 4.x).
    Поэтому, тут дело случая. Опасность применения вышеуказанных инструкций отсутствует.
    Кстати, по просьбе Nexius, скорее всего, всё будет преобразовано в единую библиотеку (с ещё несколькими добавленными функциями).

  10. #8
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от SooBad Посмотреть сообщение
    Да, разницы никакой нет. Это вполне очевидно.
    Всё упирается лишь в восприятие кода и совместимости. (Некоторые не знают про данный оператор, либо используют pawn 4.x).
    Поэтому, тут дело случая. Опасность применения вышеуказанных инструкций отсутствует.
    Равно как и отсутствует хоть мало-мальски внятная причина обфусцировать свой код. Зато проглядывается намерение устроить показуху.

    Справедливости ради стоит отметить, что возможность оптимизировать код с помощью #emit есть, но она совсем небольшая: если преобразовать выражение "degr_count |= 0b11 << (0b10 * i);", то в последующем коде "temp = value & degr_count" можно избежать лишнюю загрузку значения из degr_count в один из регистров.


    Также хотелось бы отдельно указать на "плюсы" реализации, которые тоже очень и очень сомнительны.

    Не требует преобразований целочисленных значений в вещественные, в отличие от того же floatsqroot.
    Если вы видите в этом препятствие производительности, то функция int_sqrt потребует ещё больше ресурсов.
    Чтобы не быть голословным, предоставлю тест производительности.

    Профайлер: http://pro-pawn.ru/showthread.php?12585

    Настройки:
      Открыть/закрыть

    PHP код:
    /*======== Настройки =========================================================*/
    const PROFILER_ITERATIONS_MAJOR 10_000;
    const 
    PROFILER_ITERATIONS_MINOR 100;

    new const 
    code_snippets_names[2][] =
    {
        {
    "int_sqrt"},
        {
    "float+floatsqroot+floatround"}
    };

    stock int_sqrt(value)
    {
        new
            
    result,
            
    temp,
            
    degr_count;

        for(new 
    3>= 0i--)
        {
            
    degr_count |= 0b11 << (0b10 i);

            
    #emit load.s.pri value
            #emit load.s.alt degr_count
            #emit and
            #emit stor.s.pri temp

            
    returning:
            
    result ^= 0b1 << i;

            if(
    temp < (result result))
                goto 
    returning;
        }
        return 
    result;
    }

    #define Prerequisites();\
        
    static i;
        const 
    TEST_MIN_VALUE 1TEST_MAX_VALUE 100TEST_STEP 5;

    #define CodeSnippet0();\
        
    for (TEST_MIN_VALUE<= TEST_MAX_VALUE+= TEST_STEP)\
            
    int_sqrt(i);

    #define CodeSnippet1();\
        
    for (TEST_MIN_VALUE<= TEST_MAX_VALUE+= TEST_STEP)\
            
    floatround(floatsqroot(float(i)), floatround_tozero);
    /*======== Конец настроек ===================================================*/ 


    Вывод:
    Код:
    Тестирование: <int_sqrt> vs <float+floatsqroot+floatround>
    Режим: интерпретируемый, 10000x100 итераций.
    int_sqrt: 15672
    float+floatsqroot+floatround: 1708
    Код:
    Тестирование: <int_sqrt> vs <float+floatsqroot+floatround>
    Режим: с JIT-компиляцией, 10000x100 итераций.
    int_sqrt: 1365
    float+floatsqroot+floatround: 880
    Связка "float+floatsqroot+floatround" требует вызова трёх нативных функций, но затраты окупаются за счёт быстрого вычисления корня математическим сопроцессором, что ничуть не удивительно: он специально создан для подобных задач.


    При написании независимых систем вам не придётся подгружать библиотеку float для подсчётов, с применением лишь одной функции.
    "Независимых систем"? Кому в здравом уме нужна будет независимость от библиотеки float?
    У неё слишком обширный набор функций? Нет, в ней только основные функции для работы с вещ. числами. Возможно, этих функций там даже слишком мало - не хватает обратных тригонометрических функций, которые реализованы отдельно в SA-MP.
    Ок, может быть это чья-то сторонняя библиотека, которую не хотелось бы лишних раз таскать за собой? Нет, это один из стандартных модулей Pawn AMX.
    Тогда, может модуль amxfloat специфичен для какой-то программно-аппаратной платформы и имеет проблемы с переносимостью? И снова мимо. Это всего лишь вещественные числа, которые есть практически на любой аппаратной платформе (кроме, разве что, каких-то малоизвестных и узкоспециализированных), а потому можно даже не задумываться о переносимости модуля - он портируется так же просто, как и остальные. К слову, куда больше проблем с портированием может возникнуть у модулей amxfile, amxcons и amxdgram (неполноценная стандартная библиотека C, нетривиальный API для работы с консолью, etc.), так что amxfloat здесь, наоборот, самый простой.

    Единственное удобство int_sqrt, которое мне приходит в голову, так это более короткая запись. Такое себе преимущество, поскольку оно легко достигается с помощью макросов.
    PHP код:
    #define int_sqrt(%0)\
        
    floatround(floatsqroot(float(%0)), floatround_tozero
    Последний раз редактировалось DeimoS; 03.05.2017 в 18:47. Причина: Убрал "настройки" в тег [php]
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  11. 2 пользователя(ей) сказали cпасибо:
    Geebrox (03.05.2017) MISTER_GONWIK (05.05.2017)
  12. #9
    Аватар для SooBad
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.04.2017
    Адрес
    Краснодар
    Сообщений
    83
    Репутация:
    20 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Справедливости ради стоит отметить, что возможность оптимизировать код с помощью #emit есть, но она совсем небольшая: если преобразовать выражение "degr_count |= 0b11 << (0b10 * i);", то в последующем коде "temp = value & degr_count" можно избежать лишнюю загрузку значения из degr_count в один из регистров.
    Читабельность это никак не снижает. Загрузка в регистры - это самая что не наесть маломальская затрата, которую только можно вызвать. Считанные микросекунды.
    Разница между прямой генерацией запроса и задействования побитовой операции - 10-20 млс(на большом кол-ве итераций). Совершенно несущественно.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Если вы видите в этом препятствие производительности, то функция int_sqrt потребует ещё больше ресурсов.
    Чтобы не быть голословным, предоставлю тест производительности.
    Увы, но более скоростного варианта реализации я не придумал. Буду рад, если что-то в этом роде будет предложено.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Возможно, этих функций там даже слишком мало - не хватает обратных тригонометрических функций, которые реализованы отдельно в SA-MP.
    Тригонометрия совершенно не нужна в сфере сампа. Ибо никаких возможностей по созданию собственных граф.движков и схожего с этим - нету. Иногда они задействуются для более точного вычисления угла поворота персонажа, но это не обратные тригонометрические функции.

  13. #10
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от SooBad Посмотреть сообщение
    Читабельность это никак не снижает.
    Скажите это большинству пользователей, которые, как правило, не знают #emit. Пускай посмеются.

    Честно говоря, я и сам не сразу понял, что именно делает эта ассемблерная вставка. Но не потому, что не знаю набора инструкций, а по причине того, что не смог понять, для чего вообще нужно было раскладывать на #emit такой простой код (серьёзно, всего 1 строка). Может вы посветите меня и других участников форума в причины столь странного решения? Ибо пока что ваш аргумент выглядит как отговорка в стиле "этот недостаток не влияет на работу, так что я его оставлю".


    Цитата Сообщение от SooBad Посмотреть сообщение
    Разница между прямой генерацией запроса и задействования побитовой операции - 10-20 млс(на большом кол-ве итераций). Совершенно несущественно.
    "Генерацией запроса"? О чём вы? Мы же не с базой данных работаем... или я что-то пропустил?


    Цитата Сообщение от SooBad Посмотреть сообщение
    Увы, но более скоростного варианта реализации я не придумал. Буду рад, если что-то в этом роде будет предложено.
    В моём посте выше уже предложен вариант. И это если не считать ещё одного, который описан устно.


    Цитата Сообщение от SooBad Посмотреть сообщение
    Тригонометрия совершенно не нужна в сфере сампа.
    Если она не нужна вам, то это ещё не значит, что она не нужна никому.


    Цитата Сообщение от SooBad Посмотреть сообщение
    Ибо никаких возможностей по созданию собственных граф.движков и схожего с этим - нету.
    Ничто не мешает взять один из open source графических движков или даже "голое" API типа OpenGL и добавить привязку к Pawn. Либо можно зайти дальше и сделать программный рендеринг, если нужна минимальная зависимость от графического стека.


    Цитата Сообщение от SooBad Посмотреть сообщение
    Иногда они задействуются для более точного вычисления угла поворота персонажа, но это не обратные тригонометрические функции.
    Как на счёт арктангенса, например?
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •