2011-12-19 2 views
1

Кто-нибудь знает, как работает функция std :: sqrt()? (или, по крайней мере, есть идея?)Как работает функция std :: sqrt()?

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

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

EDIT: Не действительно сформулировать вопрос слишком хорошо ... Что меня интересует:

  • Как бы выглядела самая быстрая функция C++, вычисляющая квадратный корень? (более или менее, я просто хочу знать фактическую логику за ним)
+2

Использование константы Кармака: P – moshbear

+1

Ленточный ответ заключается в том, что для вычисления квадратного корня из значения с плавающей запятой существует, вероятно, аппаратная (FPU) инструкция. Но, конечно, существуют эмуляции программного обеспечения. –

+0

@moshbear the wut: O – xcrypt

ответ

0

В стандарте не указывается конкретная реализация.

Одним из вариантов является просмотр типичной реализации, но вы, вероятно, найдете его сильно оптимизированный ассемблер.

+0

Ну, я знал это, но предположим, что он использует самую быструю C++-функцию, чтобы вычислить ее, как бы это выглядело? – xcrypt

+1

@xcrypt: Честно говоря, я не знаю, какие библиотеки алгоритмов имеют тенденцию использовать. Я бы посмотрел на http://en.wikipedia.org/wiki/Methods_of_computing_square_roots, чтобы получить представление о некоторых методах там. И действительно, все они полагаются на итерации или приближения. –

+2

@xcrypt: поскольку все алгоритмы расчета квадратного корня основаны на численных приближениях, быстрее почти сразу подразумевается неточность. Я сомневаюсь, что вы хотите найти «самую быструю» реализацию там. –

3

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

+0

Немного ошибочно назвать это «сопроцессором», не так ли? Я не видел, чтобы он отделялся от основного процессора более чем за 20 лет. –

+0

Вот почему я CMA и включил «блок с плавающей точкой». Бьюсь об заклад, вы использовали «286 в свое время в своей жизни! –

2

Иногда он использует то, что предлагает CPU: (! Blahblah не просто так ничего отношение оптимизировано прочь, не запускать эту программу)

$ cat main.cc 
#include <cmath> 
#include <ctime> 
#include <cstdlib> 
int main(){ 
    srand (clock()); 
    const double d = rand(); 
    return std::sqrt(d) > 2 ? 1 : 0; 
} 

$ g++ -S main.cc 
$ cat main.s 
    .file "main.cc" 
    .text 
    .p2align 4,,15 
.globl main 
    .type main, @function 
main: 
.LFB106: 
    .cfi_startproc 
    subq $8, %rsp 
    .cfi_def_cfa_offset 16 
    call clock 
    movl %eax, %edi 
    call srand 
    call rand 
    cvtsi2sd %eax, %xmm1 
    sqrtsd %xmm1, %xmm0 
    ucomisd %xmm0, %xmm0 
    jp .L5 
.L2: 
    xorl %eax, %eax 
    ucomisd .LC0(%rip), %xmm0 
    seta %al 
    addq $8, %rsp 
    .cfi_remember_state 
    .cfi_def_cfa_offset 8 
    ret 
.L5: 
    .cfi_restore_state 
    movapd %xmm1, %xmm0 
    call sqrt 
    jmp .L2 
    .cfi_endproc 
.LFE106: 
    .size main, .-main 
    .section .rodata.cst8,"aM",@progbits,8 
    .align 8 
.LC0: 
    .long 0 
    .long 1073741824 
    .ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2" 
    .section .note.GNU-stack,"",@progbits 

(подсказка: он использует инструкцию sqrt-cpu)

+1

Это не _just_ использование команды 'sqrtsd', а также проверка того, что результат неупорядочен против самого себя (например, NaN), а затем вызывает фактическую библиотечную функцию, если это так. Не знаете, зачем это нужно, может быть, получить дополнительную информацию, не предоставленную самой инструкцией, возможно, обработку исключений? – paxdiablo

+0

@paxdiablo: Теперь, когда вы это говорите, я тоже удивляюсь. Я не мог найти достаточно информации о специфике инструкции sqrtsd. –

1

sqrt(); функция За кулисами.

Он всегда проверяет средние точки на графике. Пример: sqrt (16) = 4; sqrt (4) = 2;

Теперь, если вы вводите любые данные внутри 16 или 4, как sqrt (10) ==?

Он находит среднюю точку 2 и 4 i.e = x, затем снова находит среднюю точку x и 4 (она исключает нижнюю границу этого входа). Он повторяет этот шаг снова и снова, пока не получит идеальный ответ. I.e sqrt (10) == 3.16227766017. Он лежит b/w 2 и 4. Все эти встроенные функции создаются с использованием исчисления, дифференциации и интеграции.

Смежные вопросы