더 빠른 사인 기능이 있습니까?


25

3d 펄린 노이즈 생성을 위해 노력하고 있습니다. C # Math 라이브러리는 대부분의 함수가 배열을 사용하기 때문에 필요한 것에 과도하게 보입니다. 노이즈를 생성하기 위해 여러 곳에서 Math.Sin ()을 사용합니다. 누구든지 더 빠른 사인 함수를 알고 있습니까?

답변:


32

포물선을 사용하여 사인 함수의 값에 근접 할 수 있습니다. 이것은 정확히 -pi / 2 및 pi / 2에 근본을 갖는 이점이 있는데, 이는 일반적으로 TaylorSeries 또는 MaclaurinSeries 기반의 다른 빠른 근사치에는 해당되지 않습니다 .

public float Sin(float x)
{
    const float B = 4 / PI;
    const float C = -4 / (PI*PI);

    return -(B * x + C * x * ((x < 0) ? -x : x));
} 

다음은 실제 사인 함수와의 비교입니다.

대체 텍스트


3
이것은 실제로 훌륭한 솔루션입니다. 다음은 devmaster.net의 훌륭한 기사로, 왜 이것이 작동하는지 설명하고 구현 세부 정보를 제공합니다. devmaster.net/forums/showthread.php?t=5784
reverbb

나는 C #에 대해 모른다. 그러나 대부분의 C 환경에서 abs () 함수는 최적화 될 때 분기 (? : 연산자)보다 빠를 것이다.

3
이 코드가 Xbox 360 또는 Windows Phone 7에서 실행될 수 있다고 가정했기 때문에 Math.Abs ​​() 호출을 제거했습니다. Xbox 360의 JIT 컴파일러는 아무것도 인라인하지 않습니다. Math.Abs ​​() 호출은 실제로 더 비쌉니다.
zfedoran


1
@zfedoran 왜 반환 값을 무시합니까? 음의 사인파 인 것 같습니다.
Daniel Pendergast

12

sin () 함수 에 대한 입력 값 범위는 무엇입니까 ? 당신이 그것을 사용하는 것에 대해, 그것들이 제한되어있는 것처럼 들리 므로 값을 미리 계산할 수 있습니다 . 예를 들어, 입력 값을 가장 가까운 자리로 반올림하는 경우 가능한 값은 360 개뿐입니다. 사전 계산하고 테이블에 저장하면됩니다.

소수점 이하 자릿수와 같이 약간 더 많은 값이 필요한 경우 테이블에서 보간 할 수 있습니다. 펄린 노이즈에 익숙하지 않지만 "노이즈"라는 단어는 높은 정확도가 필요하지 않은 것으로 보입니다. :) (또한 더 큰 테이블을 만들 수 있으며 3600 개의 항목은 공간이 많지 않습니다).


3
속도가 가장 중요한 관심사이고 약간의 정확성을 희생하지 않는다면 이것이 가장 좋은 대답입니다.
AttackingHobo

1
나는 "최고"에 대해 모른다-다른 답변에서 볼 수 있듯이 5 ops + abs (속도는 아치 / 컴파일러에 따라 다르지만 종종 분기가 없음)에서 또 다른 매우 좋은 근사치를 얻을 수 있습니다. 조회 테이블이 캐시에 없으면 훨씬 느려질 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.