Zero-overhead deterministic exceptions: Throwing values //Herb Sutter
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r2.pdf
위 제안서는, try-catch 문법을 유지하면서, 구현은 error return code를 이용하는 exception 처리 모델을 제안하는데,
이때의 단점을 최적화라고 얘기하면서 이의 해결을 위해, error code리턴으로 구현하지 않고 보통의 table-based로 구현할지를
컴파일 옵션을 통해 선택하는 것도 제안한다:
pg.22
At call sites (that propagate or handle an error), a potential downside of the if-error-goto-handler implementation model
is that it injects branches that can interfere with optimizations. However, because this static exception model is
isomorphic to error codes (which the dynamic exception model is not), implementations can also choose
whether to implement this exception model as error returns or using table-based handling as a pure optimization
(no longer a required overhead).
And this was tried out in practice in a large native code system on the Midori project, which used a very similar exception design:
“A nice accident of our model [an the exception model that was isomorphic to error codes]
was that we could have compiled it with either return codes or [table-based] exceptions.
Thanks to this, we actually did the experiment, to see what the impact was to our system’s size and speed.
The exception[-table]s-based system ended up
being roughly 7% smaller and 4% faster on some key benchmarks.” — [Duffy 2015]
또 이러한 시도는 이미 이전의 다른 프로젝트에서 "in practice in a large native code system"에 있었음을 명시하면서,
table-based로 구현 했을 때 4% 속도 향상 결과를 인용하고 있다.
table-based는 현재 g++,clang, visual c++이 사용하고 있는 보통의 exception 처리 구현 방법이다.
개인적 실험에서는, g++,clang에서: 테스트 코드와 컴파일러(g++/clang), 컴파일 옵션(-O2,-O3)에 따라 들쑥날쑥하지만
전체적으론 거의 비슷하거나 exception이 약간 빨랐던거 같고,
visual c++에서는: 일관되고 확연하게(보통 3,4배이상 ~10배까지) exception이 return code보다 빨랐다.
exception처리 속도를 잴때 exception을 던져서 잡는 속도를 재면 안된다. exception처리 능력이 있는 코드에서 exception이 발생하지 않는 성공 path의 처리 속도를 재야한다.
어떤
인간은 c++ exception이 setjmp 보다도 느리다고 하는데, 현재의 table-based가 사용되기 전엔, g++에선
sjlj방식이, vitual c++에선 seh방식이 사용되었다. sjlj는 setjmp-longjmp의 약칭이다. 기본적으로,
필요한 몇개 register를 복구하고 jmp하는 식은 seh와 현재의 table-based도 같다. setjmp는 필요도 없는
거의 모든 register를 보관하기 때문에 overhead가 크다. 또한 최소한으로 구현하더라도, caller들쪽에 정의된 catch문들을
탐색하기 위해 jmp buffer들을 서로 연결해야 하는데 추가적 overhead가 발생한다. table-based방식은 jmp
buffer연결의 overhead가 없다
; 이때도 마찬가지로 longjmp되지 않는, 에러 없는 정상적 path의 속도를 비교해야 한다.
C++ 표준에, exception 대안들이 제안되는 것을 보고, 현재의 exception방식이, 모든 경우에 exception을 버리고 그 대안들을 써야할 만큼 잘못된 것이라는 게 컨센서스라는 생각을 가진 인간들이 있는거 같은데, 전혀 그렇지 않다.
위
문서 pg.13에 명시된 Ideal error handling의 특질을 보면, 현재의 exception이 다른
대안들(expected,outcom, 일반적 error code return)보다, 기능적인 측면에서 훨씬 더 이상적 특질을
만족한다. 이전의 다른 제안문도 본적이 있는데 거기서도 그렇게 기술돼 있었다. exception에 대한 그러한 평가가, 최소한
C++표준제안하는 사람들 그룹에서는, 인정되는 공통의견인 거다. 그럼에도 불구하고 현재의 exception은 치명적 약점이
있는데, real-time system에 쓰지를 못한다는 거다. 아예 쓰지를 못한다. 다른 대안들은 기능적 측면에서, 이상적
특질들을, 현재의 exception만큼도 충족시키지 못한다. (그렇기 때문에 위 문서에서와 같은 새로운 제안이 또 나온게
아니겠는가?) 그럼에도 불구하고 그 대안들은 real-time system에 쓰일 수 있다. 최소한, 어디든지 쓰일 수 있지만
가장 후지고 불편한, 그 대안들이 아니면 어쩔 수 없이 써야할, C에서도 쓰이는, 단순 error code
return방식보다는 낫기떄문에 그런 대안 모색이 필요한 것이다.
(수정: 위 문서에서 제안하는 방식은, 기존의 대안들과 다르게 모든 ideal error handling 특질을 가진 것을 주장한다. 앞으로 어떻게 될 지는 모르겠음)
이거 귀찮아서 안 읽었었는데 꼭 읽어야겠다
와 ㄷㄷ 이분도 고수시네
근데 마지막 문단이 이해가잘안감, 결국 트라이캐치 익셉션은 한계가있다는거?
현재의 익셉션이 트라이캐치를 의미하는지 아니면 다른걸 의미하는지몰겠음
현재의 exception 방식(당연히 try-catch)를 real-time system에서 못씀
그럼 결국 느려서 못쓰는거아님? 그런뜻이아닌감...
익셉션이 발생했을 때, 그 처리가 (비결정적 시간으로) 느리다는 거임 아주 가끔 느릴 수가 있는데 그 시간도 느리면 안된다는거 real-time system에서는. 또 실험적으로 충분히 빠르게 익셉션이 처리 됐다고 해도 본질적으로 담에도 그렇게 빠르게 처리된다는 보장이 없음
이건 UB model과 freeze랑 관련이 있는건데 판단은 알아서~
그리고 비교가 잘못된게 누가 abstracted error code를 C/C++에서 사용함? ㅋㅋ
무슨 비교를 잘 못했으며, abstracted error code사용한다고 누가 했나요?
그리고 여기서 이야기했던건 error handling을 거의 하지 않으면서(IO와 같은 부분들은 당연히 핸들링을 해야함) unexpected error에 대해서 stack unwinding대신 abort를 하는 방식을 이야기한거임. (noexcept)
expected,outcom 이 abstracted error handling 방식이 아님? 대부분 코드들은 -1 -2와 고전적인 에러 핸들링 방식을 사용하는데. 당연히 expected, outcome같은걸 사용하면 RTTI를 사용해야됨 (variant?)
그건 마치 vtable을 제거할 수 있는 상황에서 vtable은 느리지 않아!!! 라고 이야기하는거랑 비슷함. 당연히 없는게 빠르지.
예시 보면 safe_divide라고 불리는 함수를 무조건 호출하게 되어있는데 얘는 expected을 사용하고 이건 dynamic dispatch임
이거 도대체 뭔소리하는건지.... 하니씩 얘기합시다 expected, outcome은 RTTI가 아님. vtable은 뜬금없이 왜 나오는지 모르겠고
만약에 safe_devide함수가 non-abstracted error handling 방식을 사용했으면 코드 자체가 바뀌었을 가능성이 높음. non-conditional instruction(cmov) 위주로
예시에 safe_divide는 어디 예신가요?
뭔 개소리야 씨발 expected은 type-safe variant야
4.1.6 Side by side example.
ㄷㄷ 이게 천상계 개발자들의 싸움인가
private: bool has_val; // exposition only union { value_type val; // exposition only unexpected_type unex; // exposition only }; RTTI는 아니긴 하네 ㅋㅋ 여전히 side-effect있는 dynamic dispatch긴 하지만
개소리는 누가 개소리 참 정신없게 개소리 하시네. safe_devide함수가 non-abstracted error handling 방식을 사용하는게 뭐가 어쩄다는 거?
무슨소리하는지 모르겠으면 이게 왜 느려지고 왜 이런 결과가 나오고 이 결과가 real-world에서는 상황에 따라 충분히 바뀔 수 있는지 제대로 이해하지 않고 글 싸지른거임 ㅋㅋ 공부 더 ㄱㄱ
도대체 뭘 얘기 하고 싶으거요? 하하
그게 어쨌는지 이해를 못 하면 공부가 엄청나게 부족한거임. 컴파일러 최적화가 어떻게 이루어지는지부터 다시 공부하면 좋을듯?
딱 한번만 설명함
참 개소리도 희안하게 하시네 틀린 개소리 본인이 하시고 화를 내시네. 하하
어디서 일하길래 rtti도 아니고 유니온쓰는거로 성능떨어진다하냐;; 성능에 목숨을거네 ㄷㄷㄷ
expected는 사이즈가 매우 작기때문에 caller에서 할당될 가능성이 높음(RVO) 그 다음에 그럼 호출된 함수인 safe_divide는 caller에서 전달해준 expected 객체에 side-effect가 있는지 없는지 당연히 모름. 그러니까 branch를 동시에 execute하면 UB가 됨. 그렇지 않게 하기 위해서 BasicBlock이 분리되서 table화 되거나 standard compare and jump dispatch가 이루어질거임. 그렇게 되면 당연히 exception과 동일한 코드가 나오지만. exception은 코드가 어디까지 실행되는지에 대해 보장하지 않기때문에 추가적인 최적화가 가능함. 이런 씨발같은 상황을 만들지 않으려면 non-abstracted (non-allocated)
return value를 사용해야함. 그렇게 되면 각각의 branch들이 동시에 dispatch될 수 있는 상황이 생기고. 그럼 Instruction Selector에서 standard jump가 아니라 cmov instruction을 사용해서 CPU의 파이프라인을 최대한 사용함.
이쪽은 ^^ㅣ발 네트워크 스택 짜고 1ns만 늦어져도 커넥션 끊어지는 환경에서 작업함. 이런거에 목숨 걸어야함
이거 뭐하자는 건지. expected를 여기서 나하고 이시간에 논하자는거? 나한테 왜 그러냐 도대체? 하하
유니온을 쓰는게 문제가 아니라 has_val이 true인지 false인지 런타임에밖에 알 수없다는게 문제임.
VTune으로 3년만 프로파일링 해보면 이게 얼마나 개소린지 알 수 있음
컴파일 타임에 결정되면 컴파일 에러를 내면 되겠네
그리고 이왕 이렇게 됬으니 throw했을때 느려지는 이유도 알려줌. CPU는 최적화를 위해서 call trace cache(BTB cache안에 있음)라는걸 사용함. 즉 그러니까 call ~ ret을 기록한다는 뜻임. throw를 하면 현제 control flow를 강제하게됨. 그럼 call ~ ret pair가 안 맞게되고 돌아갔을때 원래 call 했던 함수가 아니라 다른 함수로 돌아가게됨. 그래서 이 call trace와 관련된 모든 캐시와 정보가 작살나는거임. 그래서 모든 예측에 실패함.
저런 말 하는거보면 컴파일러에대해 하나도 모르는거네 ㅋㅋ
좀 공부좀 하고 아는척좀 해라 븅신아 ㅋㅋ
본인이 call trace cache가 작살난거 같은데 도대체 내가 쓴 본글에 무슨 얘길 하고 싶은거냐? 그냥 아무거나 throw? 하하
ㅋㅋ 문제가 있어보이면 지적이라도 해보던가? 아키텍처에 대해서 하나도 모르니까 지적도 못 하겠지?
공부 더 하고 오세요 ^^
이시간에 내가 너하고 왜 이렇고 있어야 하는지 모르겠지만 니 공부한거는 너혼자 있을때 떠들고 본문에 대해서 나한테 말하는게 뭐냐? 도대체? 지혼자 맞았네 하다가 미침놈이 아니네 이지랄에. safe_divide가 여기서 뭐가 중요하며
그게 왜 중요한지 모르니까 너가 멍청하다는거야 공부 더 하라고 ㅋㅋㅋㅋㅋㅋ ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
지혼자 정신 승리네 이거 하하. 저기 제안은 단순화한 exception을 쓴다는 거다. 그안에 error code가 있고 그거 까서 본다는게 다야 알겠냐? 보이기만 throw-catch로 문볍형식만 맞춰준다는 거라고. 그래서 실질적인 구현은 error-code return 처럼 처리할 수 있다는 거다. 그런데 이게 속도가 느릴 수 있다는 거야. 답답하네 하하 너하고 너 얘기해서 뭐하냐?
니가 말한건 "exception이 느리다고?"다 멍청아 그럼 exception이 느리지 빠름? ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
멍청아 문맥을 봐. 위에 빠르다고 한건 내가 아냐. 익셉션이 발생한 이후에 처리는 느리겠지 당연
니가 말한건 "exception 느리지 않다" 고 그 이유를 저 paper를 통해서 설명한건데 저 paper는 real-world하고는 거리가 멀다 라고 말하는거임 ㅇㅋ?
발생 안 해도 느리다고 빡대가리야 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
그 발생 안 해도 느린 이유를 내가 장문으로 설명한거고 너는 못 알아들은거고 ㅇㅋ?
그래서 내가 몇번을 말하냐? 익셉션 처리가 가능한 코드의 성공 path의 속도를 재는 거라고. 위에 Herb Sutter가 인용한거 보이지? 초딩이냐? 말장난해? 이밥에 너같은 놈하고 얘기하고 있어햐 하나?
정확하게 이야기하세요~ exception 처리 가능 범위라는 기준이 뭐죠? ㅋㅋ 저 문법 비슷하게 사용하면 무조건 exception 처리 가능 범위인가?
병신놈이네. 당장 visual c++코드로 간단하게 만들어서 해봐. 위에 Herb Sutter가 잘못이네
그럼 븅신같이 "exception이 느리다고?" 라고 짓지 말고 "exception이 xx하게 핸들링할때 성공 path의 속도는 충분하다" 라고 표현하던가 ㅋㅋ 븅신새끼 지가 써놓고
와우 visual c++ 코드~ 말부터 틀딱냄시나네. 난 real-world라고 말했고 내가 현업에서 직접 경험한걸 이야기한거임. 저 짧은 코드 벤치마크 해봤자 의미없음 ㅋㅋ
익셉션 처리 가능 범위란다...하하.. 남이 하지도 않은 소리를 만들어 내고 있네
그래 뭐~ 너는 이렇게 latency intensive한거 만져볼 경험도 없고 없겠지 ㅋㅋ 그러니까 이런 말 하는거 아니겠어. 평생 그렇게 사세요 ^ㅇ^. 근데 입은 털지 말자고
병신아 너 병신짓 하는거 본인이 알고는 있니?
익셉션 처리 가능 범위가 에러코드 -1이나 -2를 리턴해도 가능한거냐고 아니면 저린식으로 abstracted handling만 포함이냐고 ㅋㅋㅋ.... 기준이 전혀 없잖아 에러코드 -1, -2로 처리 가능하면 빨라지는 경우의 수를 내가 말해준거라니까?
말 해서 뭐하냐 ㅋㅋㅋ 알려줘도 모르는데 ㅋㅋㅋ 이런 새끼한테 시간쓴 내가 잘못이지 ㅋㅋ 자러감
하하하. 병신이네. 익셉션처리 몰라? 저 제안 문서의 익셉션 처리가 아니라. 그냥 일반 익셉션. 답답하네. 바보야. 저 제안문서는 익셉션을 단순화해서 코드를 이중으로 만들 수 있는걸 제안한거고 실제로 그렇게 해서 나온 real-world -- "this was tried out in practice in a large native code system"에서의 결과가 있다고 하는데 실제 두 구현의 속도를 비교하는 거를 얘기하는거 아니냐. 답답하다.
-1,-2가 왜나오냐 이 병신아
abstracted 인지 아닌지 니가 전화해서 알아봐 병신아
유니온이 런타임 퍼포먼스에 영향이 있음? - dc App
위에 분 필기하겠읍니다. 혹시 추천하시는 최적화 서적 있으신가요?
최적화는 프로파일링에서부터 나옴. 절때로 측정 하기전에 최적화 하지 마세요. 그거 말곤 딱히 추천할만한 서적은 없음.
문득 드는 생각인데 이렇게 서로 불타는 편이 옆에서 주워먹기는 좋은 거 같네
진짜 세계관 최강자들의 싸움이다... 가슴이 웅장해진다 - dc App
뭐냐 코세 있던 그 때 프갤 같네 ㅋㅋ