나는 총 2.8GB의 개체 코드에 해당하는 엄청난 수의 기능을 가지고 있습니다 (불행히도 주위에 방법이 없습니다, 과학 컴퓨팅 ...)
링크를 시도 할 때 relocation truncated to fit: R_X86_64_32S
컴파일러 플래그를 지정하여 우회하고자하는 (예상 된) 오류가 발생합니다 -mcmodel=medium
. 내가 제어하는 것 외에 링크 된 모든 라이브러리는 -fpic
플래그 로 컴파일됩니다 .
그래도 오류가 지속되며 링크하는 일부 라이브러리가 PIC로 컴파일되지 않은 것으로 가정합니다.
오류는 다음과 같습니다.
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_fini' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x19): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_init' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o: In function `call_gmon_start':
(.text+0x7): relocation truncated to fit: R_X86_64_GOTPCREL against undefined symbol `__gmon_start__'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbegin.o: In function `__do_global_dtors_aux':
crtstuff.c:(.text+0xb): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x13): relocation truncated to fit: R_X86_64_32 against symbol `__DTOR_END__' defined in .dtors section in /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtend.o
crtstuff.c:(.text+0x19): relocation truncated to fit: R_X86_64_32S against `.dtors'
crtstuff.c:(.text+0x28): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x38): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x3f): relocation truncated to fit: R_X86_64_32S against `.dtors'
crtstuff.c:(.text+0x46): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x51): additional relocation overflows omitted from the output
collect2: ld returned 1 exit status
make: *** [testsme] Error 1
그리고 내가 연결하는 시스템 라이브러리 :
-lgfortran -lm -lrt -lpthread
문제를 찾을 수있는 단서가 있습니까?
편집 : 우선, 토론에 감사드립니다 ... 조금을 명확히하기 위해 다음과 같은 수백 가지 기능 (개별 개체 파일의 크기 약 1MB)이 있습니다.
double func1(std::tr1::unordered_map<int, double> & csc,
std::vector<EvaluationNode::Ptr> & ti,
ProcessVars & s)
{
double sum, prefactor, expr;
prefactor = +s.ds8*s.ds10*ti[0]->value();
expr = ( - 5/243.*(s.x14*s.x15*csc[49300] + 9/10.*s.x14*s.x15*csc[49301] +
1/10.*s.x14*s.x15*csc[49302] - 3/5.*s.x14*s.x15*csc[49303] -
27/10.*s.x14*s.x15*csc[49304] + 12/5.*s.x14*s.x15*csc[49305] -
3/10.*s.x14*s.x15*csc[49306] - 4/5.*s.x14*s.x15*csc[49307] +
21/10.*s.x14*s.x15*csc[49308] + 1/10.*s.x14*s.x15*csc[49309] -
s.x14*s.x15*csc[51370] - 9/10.*s.x14*s.x15*csc[51371] -
1/10.*s.x14*s.x15*csc[51372] + 3/5.*s.x14*s.x15*csc[51373] +
27/10.*s.x14*s.x15*csc[51374] - 12/5.*s.x14*s.x15*csc[51375] +
3/10.*s.x14*s.x15*csc[51376] + 4/5.*s.x14*s.x15*csc[51377] -
21/10.*s.x14*s.x15*csc[51378] - 1/10.*s.x14*s.x15*csc[51379] -
2*s.x14*s.x15*csc[55100] - 9/5.*s.x14*s.x15*csc[55101] -
1/5.*s.x14*s.x15*csc[55102] + 6/5.*s.x14*s.x15*csc[55103] +
27/5.*s.x14*s.x15*csc[55104] - 24/5.*s.x14*s.x15*csc[55105] +
3/5.*s.x14*s.x15*csc[55106] + 8/5.*s.x14*s.x15*csc[55107] -
21/5.*s.x14*s.x15*csc[55108] - 1/5.*s.x14*s.x15*csc[55109] -
2*s.x14*s.x15*csc[55170] - 9/5.*s.x14*s.x15*csc[55171] -
1/5.*s.x14*s.x15*csc[55172] + 6/5.*s.x14*s.x15*csc[55173] +
27/5.*s.x14*s.x15*csc[55174] - 24/5.*s.x14*s.x15*csc[55175] +
// ...
;
sum += prefactor*expr;
// ...
return sum;
}
객체 s
는 상대적으로 작고 필요한 상수 x14, x15, ..., ds0, ... 등을 유지하면서 ti
외부 라이브러리에서 double을 반환합니다. 보시다시피, csc[]
는 다음 형식의 개별 개체 파일 (각각 약 ~ 1MB 크기의 수백 개)에서도 평가되는 미리 계산 된 값 맵입니다.
void cscs132(std::tr1::unordered_map<int,double> & csc, ProcessVars & s)
{
{
double csc19295 = + s.ds0*s.ds1*s.ds2 * ( -
32*s.x12pow2*s.x15*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x15*s.x35*s.x45*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x35*s.x45*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.mbpow4*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.x35*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.x45*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35*s.mbpow4*s.mWpowinv2 +
32*s.x12pow2*s.x35pow2*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35pow2*s.x45*s.mWpowinv2 +
64*s.x12pow2*s.x35*s.x45*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35*s.x45pow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.mbpow4*s.mWpowinv2 +
64*s.x12*s.p1p3*s.x15pow2*s.mbpow2*s.mWpowinv2 +
96*s.x12*s.p1p3*s.x15*s.x25*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.x45*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.mbpow4*s.mWpowinv2 +
32*s.x12*s.p1p3*s.x25pow2*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.x45*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x45*s.mbpow2 +
64*s.x12*s.x14*s.x15pow2*s.x35*s.mWpowinv2 +
96*s.x12*s.x14*s.x15*s.x25*s.x35*s.mWpowinv2 +
32*s.x12*s.x14*s.x15*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.x14*s.x15*s.x35pow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x15*s.x35*s.x45*s.mWpowinv2 +
32*s.x12*s.x14*s.x25pow2*s.x35*s.mWpowinv2 +
32*s.x12*s.x14*s.x25*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x25*s.x35pow2*s.mWpowinv2 -
// ...
csc.insert(cscMap::value_type(192953, csc19295));
}
{
double csc19296 = // ... ;
csc.insert(cscMap::value_type(192956, csc19296));
}
// ...
}
그게 다예요. 마지막 단계는 모든 것을 호출 func[i]
하고 결과를 합산하는 것입니다.
이것이 다소 특별하고 특이한 경우라는 사실에 관하여 : 네, 그렇습니다. 이것은 사람들이 입자 물리학을위한 고정밀 계산을 시도 할 때 대처해야하는 것입니다.
EDIT2 : x12, x13 등이 실제로 상수가 아니라는 것도 추가해야합니다. 특정 값으로 설정되고 모든 함수가 실행되고 결과가 반환되며 다음 값을 생성하기 위해 새로운 x12, x13 등이 선택됩니다. 그리고 이것은 10 ^ 5에서 10 ^ 6 번해야합니다 ...
EDIT3 : 지금까지 제안과 토론을 해주셔서 감사합니다 ... 솔직히 말해서 정확히 어떻게해야할지 모르겠지만 어떻게 든 코드 생성시 루프를 롤업하려고 노력할 것입니다.하지만 이것이 최선의 방법입니다.
BTW, 나는 "이것은 과학적 컴퓨팅이다. 이 코드의 기초는 내가 실제로 접근 할 수없는 "블랙 박스"에서 나오는 것뿐입니다. 게다가 모든 것이 간단한 예제로 훌륭하게 작동했습니다. 그리고 저는 주로 실제에서 일어나는 일에 압도당했습니다. 세계 응용 ...
EDIT4 : 그래서 저는 csc
컴퓨터 대수 시스템 ( Mathematica ) 에서 표현을 단순화 하여 정의 의 코드 크기를 약 1/4로 줄일 수있었습니다 . 이제 코드를 생성하기 전에 다른 트릭 (이 부분을 약 100MB로 줄임)을 적용하여 다른 크기로 줄일 수있는 방법도 알고 있으며이 아이디어가 효과가 있기를 바랍니다.
이제 귀하의 답변과 관련이 있습니다. func
CAS가 많이 도움이되지 않는 s 에서 루프를 다시 롤백하려고 시도하고 있지만 이미 몇 가지 아이디어가 있습니다. 예를 들어,와 같은 변수를 기준으로 표현식을 정렬하면 s를 Python으로 x12, x13,...
구문 분석하고 csc
서로 관련된 테이블을 생성합니다. 그런 다음 적어도 이러한 부분을 루프로 생성 할 수 있습니다. 이것이 지금까지 최선의 해결책 인 것처럼 보이므로 이것을 최선의 답변으로 표시합니다.
그러나 VJo에게도 신용을 부여하고 싶습니다. GCC 4.6은 실제로 훨씬 더 잘 작동 하고 더 작은 코드를 생성하며 더 빠릅니다. 큰 모델을 사용하면 코드에서있는 그대로 작동합니다. 기술적으로 이것은 정답이지만 전체 개념을 변경하는 것이 훨씬 더 나은 접근 방식입니다.
귀하의 제안과 도움에 감사드립니다. 관심이 있으신 분은 준비가되는대로 최종 결과물을 게시하겠습니다.
비고 : 다른 답변에 대한 언급 : 제가 실행하려는 코드는 단순한 함수 / 알고리즘의 확장과 어리석은 불필요한 풀기에서 비롯된 것이 아닙니다. 실제로 일어나는 일은 우리가 시작하는 것은 매우 복잡한 수학적 객체이고 그것들을 수치 적으로 계산 가능한 형태로 가져 오면 이러한 표현이 생성 된다는 것 입니다. 문제는 실제로 근본적인 물리적 이론에 있습니다. 중간 표현의 복잡성은 팩토리얼로 확장되는데, 이는 잘 알려진 사실이지만,이 모든 것을 물리적으로 측정 할 수있는 것으로 결합하면 (관찰 가능한) 표현의 기초를 형성하는 매우 작은 함수 몇 개로 귀결됩니다. (일반적으로 만 사용할 수 있는이 점에서 "잘못된"것이 있습니다.ansatz ( "perturbation theory"라고 함)) 우리는이 ansatz를 더 이상 분석적으로 실행 불가능하고 필요한 기능의 기초가 알려지지 않은 다른 수준으로 가져 오려고합니다. 그래서 우리는 이것을 이렇게 무차별 대입하려고합니다. 최선의 방법은 아니지만 결국 물리학에 대한 우리의 이해를 돕는 방법 이길 바랍니다.
최종 편집 :
모든 제안 덕분에, 나는 티카와가 코드 생성기의 수정 사용, 상당히 코드 크기를 줄이기 위해 관리했습니다 func
상단 응답의 라인을 따라 다소들 :)
csc
Mathematica로 함수를 단순화하여 92MB로 줄였습니다. 이것은 환원 불가능한 부분입니다. 첫 번째 시도는 오랜 시간이 걸렸지 만 일부 최적화 후 단일 CPU에서 약 10 분 만에 실행됩니다.
에 미치는 영향 func
은 극적이었습니다. 전체 코드 크기가 약 9MB로 줄어 들었으므로 이제 코드는 총 100MB 범위에 속합니다. 이제 최적화를 켜는 것이 합리적이며 실행이 매우 빠릅니다.
다시 한 번, 여러분의 제안에 감사드립니다. 많은 것을 배웠습니다.
mmap
런타임에 외부 바이너리에서 직접 데이터를 이동해야 합니다.