2013-09-21 17 views
1

주로 행렬 곱셈, 덧셈 등을 수행하는 C++ 프로그램이 있습니다.수백만 번의 실행 후 C++ 프로그램 안정성

문제는 계산이 약 3 백만 번 수행 될 때 EXC_BAD_ACCESS가 발생한다는 것입니다.

문제가 수백만 번 또는 몇 시간 동안 실행될 때 발생할 수있는 문제가 있습니까? 프로그램

상세 :

프로그램은 다른 범위의 값에 간단히 계산이므로 동시에 6 개 스레드상에서 실행된다. 스레드 간에는 자원 공유가 없습니다.

이후 프로그램에는 분명 문제가 없을 것 같다 : 더 메모리 누수가 없다

  1. , 나는 악기를 사용하여이 확인했습니다, 그리고 프로그램의 메모리 크기는 안정적이다.
  2. 프로그램은 아무런 문제없이 각 스레드에서 최소 200 만 번 실행할 수 있지만 EXC_BAD_ACCESS 예외가 일부 스레드에서 발생하는 것으로 거의 보장됩니다. 때로는 행렬의 크기가 약 2 * 곱하기 2 * 1000 2

    : 행렬의 곱셈에 대해

(예외는 프로그램의 제 2 개 시도 (2/2)에서 발생).

매트릭스의 요소는 사용자 지정 복합 번호 클래스입니다.

요소의 값은 rand()에 의해 임의로 생성되고 float로 변환됩니다.

구조는 다음과 같이이다 :

class Complex 
{ 
private: 
    float _real, _imag; 
public: 
    // getters, setters and overloaded operators 
}; 

class Matrix 
{ 
private: 
    Complex **_values; 
    int _row,_col; 
public: 
    getters, setters and overloaded operators 
}; 

대단히 감사합니다!

크래시에 대한 가능한 모든 이유가 크게 환영합니다!

+2

'EXC_BAD_ACCESS'는 대개 코드의 버그 또는 불안정한 하드웨어를 의미합니다. – Mysticial

+0

실제 코드를 보지 않고도 알기가 어렵습니다. – Escualo

+0

# 신비 : 음 ... 문제의 버그가있을 수 있습니다 ... 아직 명확하지 않습니다 ... 버그의 유형에 대한 힌트를 좀 주시겠습니까? 아 ... 불안정한 하드웨어가 가능합니다 ... 맥 OS X 10.8, Xcode 5 with llvm 5를 사용하고 있습니다. 우분투에서 이런 유형의 과학 계산이 더 잘 된 것 같습니다. complier에 대한 개조하면 도움이 될 것입니다 모르겠다 ... – Lewen

답변

2

EXC_BAD_ACCESS는 프로세스의 현재 메모리 공간을 가리 키지 않는 포인터를 역 참조한다는 것을 의미합니다. 이것은 코드의 버그입니다. 실패 할 때까지 디버거에서 실행 한 다음 실패한 명령문의 변수 값을 살펴보십시오. 그것은 단순하거나 매우 미묘 할 수 있습니다.

+0

예, 프로세스의 메모리 공간 ... #Graham Perks가 위에서 지적한 것처럼 해결책 인 것 같습니다. 문제는 스레드에 관한 것 같습니다. – Lewen

+0

문제는 메모리 공간과 관련이 있습니다. #Graham Perks는 더 명확하게 지적했지만, 멀티 스레딩없이 프로그램을 실행하면 몇 번이나 반복 할 수 있습니다. – Lewen

1

귀하의 게시물에 결정적인 대답을 하기엔 너무 적은 정보가 있습니다. 그러나 현재 사용할 수있는 정보가 없으므로 더 신중하게 디버깅해야합니다. 여기 내가하는 일이있다.

디버깅하려면 반복성이 필요합니다. 하지만 ... 당신은 난수를 사용하고 있다고 말합니다. 여러분의 프로그램이하는 것은 과학적인 계산입니다. 대부분의 경우 실제로 "실제"임의성은 필요하지 않지만 통계 테스트를 통과하는 "반복 가능"임의성 - 임의성이 필요하지만 난수 생성기를 재설정 할 수있는 충분한 데이터가있는 경우에는 다음과 똑같은 결과가 나타납니다. 이전 실행. 이를 위해 새 계산 블록을 시작할 때마다 현재 RNG 상태 (예 : 시드)를 적어 둘 수 있습니다.

이제 몇 분에 한 번 계산 (RNG 포함)을 다시 시작하는 데 필요한 모든 상태를 저장하는 코드를 작성하고 프로그램을 실행하십시오.이렇게하면 코드가 충돌하면 똑같은 상태로 계산을 다시 시작하고 수백만 번의 반복을 기다리지 않고 추락 할 수 있습니다. 여기에 RNG를 제외하고 다른 강력한 외부 상태 (네트워크 작업, IO, 스레드 스케줄링시 특정 선택을하는 프로세스 스케줄러 등)에 의존하지 않는 RNG를 제외하고 강력한 가정을하고 있습니다.

데이터의 경우 기계 결함 (과열, 불량 메모리 등)으로 인한 문제인지 쉽게 테스트 할 수 있습니다. 충돌 전 마지막 상태로 계산을 다시 시작하십시오. 시스템을 식히면 어쩌면 다시 시작해야 할 수도 있습니다. 다른 충돌이 발생하면 (그리고 코드를 다시 시작할 때마다 발생합니다), 그 원인은 다음과 같습니다. 코드의 버그.

그렇지 않으면 우리는 여전히 컴퓨터 오류라고 말할 수 없습니다. 코드가 순수 사고/코드 실수로 인해 제어에서 벗어나는 요인에 따라 정의되지 않은 동작으로 인해 중단 될 수 있습니다. 예를 들어, 거의 사용되지 않은 코드 경로에서 초기화되지 않은 포인터를 사용하는 경우가 있습니다. 가끔씩 잘못된 액세스가 발생할 수 있으며, 포인터가 할당 된 메모리를 가리키는 경우에는 눈에 띄지 않게됩니다. valgrind을 시도하십시오. 이것은 아마도 메모리 문제를 확인하는 가장 좋은 도구 일 것입니다 ... 실행 속도가 너무 느려서 대기 상태가 아닌 의심스러운 상태 (충돌 전 마지막 상태)에서 계산을 다시 실행하는 것을 다시 좋아할 것입니다. 반복의 수백만을 위해. 나는 5 배에서 100 배까지의 속도 저하를 보았다.

그동안 다른 컴퓨터에서 코드를 실행 해보십시오. 유사한 반복 횟수의 충돌 후에도 충돌이 발생한다면 (원래 시스템에서 충돌하는 것보다 적어도 3 배 이상의 반복을 기다리십시오), 코드에서 버그 일 가능성이 큽니다.

해피 해킹!

+0

팁 주셔서 감사합니다! 예, 저는 과학적 계산과 C++을 사용하고 있습니다. 왜냐하면 단순히 OO 코드를 작성하는 것이 훨씬 더 빠르며 Matlab보다 빠르기 때문입니다. valgrind에서 메모리 액세스 문제를 확인하고 RGN 상태를 기록하려고합니다. – Lewen

0

수백만 번의 반복 작업 후에도 유한 정밀도의 계산이 실패합니까? 그것은 누적 오차가 될 수 있습니다. 문제는, 그것들은 보통 제로 또는 다른 수학적 오류에 의한 나눗셈으로 나타난다는 것입니다. EXC_BAD_ACCESS은 그렇지 않습니다. 그러나 수학 결과를 배열 인덱스로 사용하는 경우가 있습니다.

+0

감사합니다.하지만 문제는 #Graham Perks 및 #EJP가 위에서 지적한 것처럼 스레드 및 메모리 덮어 쓰기와 관련이있을 가능성이 큽니다. 프로그램을 6 개 스레드에서 4 개 스레드로 변경했습니다. 현재 11 시간 54 분 동안 실행 중이므로 아무런 문제가 없습니다. – Lewen