2017-11-05 13 views
1

나는 빛 전송의 수치 시뮬레이션, 리눅스, C++ 11에서 경로 추적을 쓰고 있어요 그리고 난 결국 실행 중에 발생할 수있는 수치 오류 잡기 위해 디버그특정 C++ 11 코드 세그먼트에 대해서만 SIGFPE 생성을 {활성화 | 비활성화} 할 수 있습니까?

#include <fenv.h> 
... 
feenableexcept(FE_INVALID | 
       FE_DIVBYZERO | 
       FE_OVERFLOW | 
       FE_UNDERFLOW); 

을 사용하고 있습니다 .

코드의 일부 지점에서 축 정렬 경계 상자 (AABB)에 대한 광선 (선분)의 교차를 계산해야합니다. 이 계산에서는 IEEE 754 표준에 설명 된 몇 가지 특수 값 (예 : NaN 및 inf)의 생성에 의존하는 매우 최적화 된 강력한 ray-box intersection algorithm을 사용하고 있습니다. 분명히,이 광선 - 박스 교차 루틴에 의해 특별히 생성 된 부동 소수점 예외를 포착하는 것에는 관심이 없습니다.

따라서, 제 질문은 :

  1. 가 (즉, 선 박스 교차 코드 섹션) 코드의 일부 부분에 대해 부동 소수점 예외 신호 (SIGFPE)의 발생을 중지시킬 수 있는가?
  2. 시뮬레이션을 계산할 때 우리는 매우 성능에 대해 우려하고 있습니다. 특정 코드 섹션에 대해서만 예외 신호를 억제 할 수있는 경우 컴파일 시간이 (즉, 세대 동안 코드를 인스트루먼트/디 인스트루먼트함으로써 값 비싼 함수 호출을 피할 수 있음)에서 수행 할 수 있습니까?

도움 주셔서 감사합니다!

+0

다른 코드에서 부동 소수점 트래핑을 설정 하시겠습니까? 부동 소수점 트래핑은 일반적으로 기본적으로 비활성화되어 있습니다.이 경우에는 경로 추적 코드에서 이미 해제되어 있으므로 다른 코드에서 부동 소수점 트래핑을 특별히 필요로하지 않는 한 다른 코드에 대해서는이 기능을 켜지 않아도됩니다. –

+0

@EricPostpischil 현재 전체 코드에 대해 부동 소수점 트래핑을 설정했습니다 (코드에서 발췌 한 코드를 사용하여). 내가하고 싶은 것은 특정 코드 섹션을 제외하고 전체 코드에 대해 부동 소수점 트래핑을 사용하도록 설정하는 것입니다. –

답변

1

표준 C++는 부동 소수점 트래핑 활성화 또는 비활성화로 실행해야하는지에 대해 컴파일 타임에 코드를 표시 할 수있는 방법을 제공하지 않습니다. 실제로, 부동 소수점 환경을 조작하기위한 지원은 표준에 의해 요구되지 않으므로, 구현이 가지고 있는지 여부는 구현에 따라 다릅니다. 표준 C++ 이상의 모든 대답은 사용중인 특정 하드웨어 및 소프트웨어에 따라 다르지만 그 정보를보고하지 않았습니다.

일반적인 프로세서에서 프로세서 제어 레지스터를 변경하면 부동 소수점 트래핑을 활성화 및 비활성화 할 수 있습니다. 이 작업을 수행하는 데 함수 호출이 필요하지 않지만 질문에 제안하는 것처럼 비용이 많이 드는 함수 호출이 아닙니다. 실제 명령어는 프로세서가 명령어 실행을 직렬화해야하기 때문에 시간을 소비 할 수 있습니다. (최신 프로세서는 수백 개의 명령을 동시에 실행할 수 있습니다. 일부는 디코드되고 일부는 프로세서 내의 서브 유닛을 기다리고, 일부는 다양한 계산 단계에서, 일부는 결과를 일반 레지스터에 쓰는 등의 작업을 수행 할 수 있습니다. 제어 레지스터 인 경우, 프로세서는 현재 실행중인 모든 명령어가 완료 될 때까지 기다린 다음 레지스터를 변경하고 새로운 명령어의 실행을 시작해야 할 수도 있습니다.) 하드웨어가 이러한 방식으로 동작하면이를 해결할 방법이 없습니다. (일반적으로 이러한 하드웨어를 사용하면 제어 레지스터를 변경하기 위해 런타임 명령을 실제로 실행하지 않고도 코드를 컴파일하거나 트랩하지 않고 코드를 컴파일 할 수 없습니다.)

시간 비용을 완화 할 수 있습니다 경로 추적 계산을 일괄 처리하므로 전체 그룹에 대해 부동 소수점 제어 레지스터에 대한 두 가지 변경 사항 (하나는 트랩을 끄고 하나는 켜기 위해)을 사용하여 그룹에서 수행됩니다.

+0

"... 부동 소수점 트래핑은 프로세서 제어 레지스터를 변경하여 구현할 수 있습니다.이 작업을 수행하는 데 함수 호출이 필요하지 않습니다 ..."? 나는 "feenableexcept()"를 사용하여 트래핑을 활성화/비활성화하는 데 사용되었습니다 ... 어떻게 제어 레지스터에서 직접 수행 할 수 있습니까? –

+0

@ChristianPagot : 프로세서에는 제어 레지스터를로드하고 저장하는 인텔의 "LDMXCSR"및 "STMXCSR"과 같은 지침이 있습니다. 일반적으로 직접 액세스하지 않습니다. feenableexcept 루틴이 대신 해줍니다. 직접 액세스 할 경우 어셈블리 코드를 삽입하거나 어셈블리 언어 소스 파일을 사용하려면 컴파일러의 특수 기능 (예 : GCC의 "asm")을 사용해야하며 컴파일러와 운영 체제에 대한 특별한 지식이 필요합니다. 지원하는 방식으로이를 수행 할 수 있습니다 (또는 적어도 용인 할 수 있음). 일반적으로 아무런 의미가 없습니다. feenableexcept를 호출하면됩니다. –

+0

@ChristianPagot : 궁극적으로 요점은 feenableexcept에 대한 실제 함수 호출이 비싸지 않다는 것입니다. 함수 호출을 구현하는 명령어의 실행 시간은 작습니다. 값 비싼 프로세서 상태가 변경되므로 부동 소수점 트랩 설정을 변경할 때 프로세서 상태를 변경하지 않아야합니다. –