2013-10-27 5 views
13

C/C++에서 특정 알고리즘을 구현하여 해결해야하는 대부분의 과학적 컴퓨팅 문제는 배정도보다 훨씬 낮은 정확도를 요구합니다. 예를 들어, 1e-6, 1e-7의 정확도는 ODE 해결사 또는 수치 적분의 경우의 99%을 포함합니다. 우리가 더 높은 정확도를 필요로하는 드문 경우에도, 일반적으로 수치 방법 자체가 실패하여 배 정밀도에 가까운 정확도에 도달 할 것을 꿈꿉니다. 예 : 둥근 오차 때문에 표준 노 스미스 상미 분 방정식을 풀 때조차도 단순한 Runge-Kutta 방법으로 1e-16의 정확도를 기대할 수 없습니다. 이 경우 배정 밀도 요구 사항은 잘못된 대답에 대해 더 나은 근사를 요구하는 것과 유사합니다.부동 소수점 최적화 - 지침

그런 다음 공격적인 부동 소수점 최적화는 코드를 더 빨리 (훨씬 더 빠르게!) 만들 수 있으므로 대부분의 경우 윈 - 윈 (win-win) 상황 인 것으로 보이며 특정 문제의 대상 정확도에 영향을주지 않습니다. 즉, 특정 구현/코드가 fp 최적화에 대해 안정적인지 확인하는 것이 현저합니다. 고전적이며 (다소 불안한) 예 : GNU 과학 도서관 인 GSL은 시장의 표준 수치 라이브러리 일뿐만 아니라 매우 잘 쓰여진 라이브러리입니다 (더 나은 일을한다고 상상할 수는 없습니다). 그러나 GSL은 fp 최적화에 안정적이지 않습니다. 사실, 인텔 컴파일러로 GSL을 컴파일하면, 예를 들어 -fp-model strict 플래그를 켜고 fp 최적화를 해제하지 않으면 내부 테스트가 실패합니다.

따라서 제 질문은 적극적인 부동 소수점 최적화에 안정적인 코드를 작성하기위한 일반적인 지침이 있는지입니다. 이 지침은 언어 (컴파일러)에 따라 다릅니다. 그렇다면 C/C++ (gcc/icc) 모범 사례는 무엇입니까?

참고 1 :이 질문은 gcc/icc에서 fp 최적화 플래그가 무엇인지 묻지 않습니다.

참고 2 :이 질문은 C/C++ 최적화에 대한 일반적인 지침 (많은 기능을하는 작은 함수에는 가상 함수를 사용하지 않는 것과 같은)을 요구하지 않습니다.

참고 3 :이 질문은 x/x -> 1과 같은 대부분의 표준 fp 최적화 목록을 묻지 않습니다.

참고 4 : 나는 이것이 고전적인 "The Coolest Server Names"와 비슷한 주관적/주제 외 질문이 아닐 것이라고 강력히 믿습니다. 의견이 일치하지 않으면 (구체적인 예/코드/문제를 제공하지 않기 때문에) 커뮤니티 위키로 신고하십시오. 나는 몇 가지 상태 점수를 얻는 것보다 대답에 훨씬 더 관심이 있습니다 (중요하지는 않습니다 - 당신은 요점을 얻습니다!).

+2

오류가 누적됩니다. 모든 계산이 배정도로 수행되는 경우에도 최종 결과는 마지막 비트까지 정확하지 않습니다. float를 어디서나 사용한다면 적절한 오류 분석을 수행하여 답변의 몇 비트가 신뢰할 만한지 계산해야합니다. 물론 두 배로 똑같은 일을해야합니다. –

+2

일반적인 수치 안정성은 종종 유한 정밀 부동 소수점 연산의 비 연관 특성을 극복하기 위해 특별히 고안된 신중하게 선택되고 거의 취약한 중간 단계를 통해 이루어집니다. 적극적인 최적화는 예를 들어 실행 순서를 변경하여 반복적 인 조정이 도움이 될 수 있지만 답을 얻는 데 더 많은 시간이 걸립니다. Pro Tip : 질문을 [Computational Science] (http://scicomp.stackexchange.com/) 사이트에 게시하고 싶을 수 있습니다. –

답변

12

컴파일러 제조업체는 종류의 최적화가 numerically stable algorithms 이상의 이러한 최적화의 영향이 미미하다는 주장에 정당화합니다.

따라서 이러한 최적화에 견고한 코드를 작성하려는 경우 충분한 조건은 수치 적으로 안정적인 코드를 작성하는 것입니다.

이제 질문은 "어떻게 수치 적으로 안정적인 코드를 작성합니까?"일 수 있습니다. 귀하의 질문이 약간 넓을 수있는 곳입니다 : 주제에 전적으로 관련된 책 전체가 있습니다. 이미 링크 된 Wikipedia 페이지에는 좋은 예가 들어 있으며 here은 좋은 예입니다. 특히 책을 추천 할 수는 없었습니다. 이것은 제 전문 분야가 아닙니다.

참고 1 : 수치 안정성의 바람직한 점은 컴파일러 최적화를 넘어서는 것입니다. 선택이 있다면 -ffast-math 스타일 최적화를 사용하지 않으려는 경우에도 수치 적으로 안정적인 코드를 작성하십시오. 수치 적으로 불안정한 코드는 엄격한 IEEE 754 부동 소수점 의미론으로 컴파일 된 경우에도 잘못된 결과를 제공 할 수 있습니다.

참고 2 : -ffast-math- 스타일 플래그로 컴파일 할 때 외부 라이브러리가 작동 할 것으로 기대할 수 없습니다. 부동 소수점 전문가가 작성한이 라이브러리는 IEEE 754 계산 속성으로 미묘한 트릭을 수행해야 할 수도 있습니다. 이러한 종류의 트릭은 -ffast-math 개의 최적화를 통해 손상 될 수 있지만 컴파일러가 예상 한 것보다 더 많은 성능을 향상시킵니다. 부동 소수점 계산의 경우 도메인 지식을 가진 전문가가 매번 컴파일러를 능가합니다. 예를 들어 CRlibm에있는 트리플 더블 구현이 많습니다. 이 코드는 엄격한 IEEE 754 의미 체계로 컴파일되지 않으면 중단됩니다. 컴파일러 최적화가 중단시키는 또 다른 기본 알고리즘은 Kahan summation입니다. 안전하지 않은 최적화를 사용하여 컴파일하면 c = (t - sum) - yc = 0으로 최적화됩니다. 이것은 물론 알고리즘의 목적을 완전히 무효로 만듭니다.

+1

라이브러리가 "-ffast-math"로 작동하는 것은 불가능하지 않습니다. GSL 개발자의 목표 중 하나는 GSL을 안정적인 수학에서 안정적으로 만드는 것입니다 (GSL 메일 목록에 대한 보고서에 따르면). 그들은 어려울 것이라고 말합니다 (그러나 불가능한 것은 아닙니다). 또한 GSL은 매우 안정적이고 안정적인 알고리즘 만 구현합니다. 따라서 해결이 불가능하지 않은 코드 문제 =>이를 달성하기 위해 C/C++에 일반적인 기술이 있어야합니다. –

+2

@ViniciusMiranda "외부 라이브러리를 기대할 수 없다"고했습니다. 모든 부동 소수점 라이브러리에 대한 일반적인 설명입니다. 부동 소수점 라이브러리 F를 원하지 않는다면, F가'-ffast-math'로 동작 할 것으로 기대할 수 있습니다. GSL의 저자가 이러한 옵션과의 호환성을 목표로한다면, 그들에게 도움이 될 것입니다. 모든 사람들이하지는 않지만 어떤 경우에는 내가 언급 한 이유 때문에 심지어 말이되지 않습니다. –