C ++ 11 클로저에 대해 올바르게 생각 std::function
하는 방법과 구현 방법 및 메모리 처리 방법 에 대한 정보를 원합니다 .
나는 조기 최적화를 믿지 않지만 새로운 코드를 작성하는 동안 내 선택의 성능 영향을 신중하게 고려하는 습관이 있습니다. 또한 비 결정적 메모리 할당 / 할당 해제 일시 중지를 피해야하는 마이크로 컨트롤러 및 오디오 시스템에서 상당한 양의 실시간 프로그래밍을 수행합니다.
따라서 C ++ 람다를 사용하거나 사용하지 않을 때를 더 잘 이해하고 싶습니다.
내 현재 이해는 캡처 된 클로저가없는 람다가 C 콜백과 똑같다는 것입니다. 그러나 환경이 값 또는 참조로 캡처되면 스택에 익명 개체가 생성됩니다. 값 폐쇄가 함수에서 반환되어야 할 때 하나는 그것을 std::function
. 이 경우 클로저 메모리는 어떻게됩니까? 스택에서 힙으로 복사됩니까? 가 해제 될 때마다 std::function
해제 std::shared_ptr
됩니까?
실시간 시스템에서 람다 함수 체인을 설정하여 B를 A에 연속 인수로 전달하여 처리 파이프 라인 A->B
을 만들 수 있다고 상상합니다 . 이 경우 A 및 B 클로저는 한 번 할당됩니다. 스택 또는 힙에 할당되는지 확실하지 않지만. 그러나 일반적으로 실시간 시스템에서 사용하는 것이 안전 해 보입니다. 반면에 B가 반환하는 람다 함수 C를 생성하면 C에 대한 메모리가 반복적으로 할당되고 할당 해제되므로 실시간 사용에 적합하지 않습니다.
의사 코드에서 DSP 루프는 실시간으로 안전 할 것이라고 생각합니다. A가 해당 인수를 호출하는 블록 A와 B를 처리하고 싶습니다. 이 두 함수는 모두 std::function
객체를 반환 하므로 해당 환경이 힙에 저장 f
되는 std::function
객체가됩니다.
auto f = A(B); // A returns a function which calls B
// Memory for the function returned by A is on the heap?
// Note that A and B may maintain a state
// via mutable value-closure!
for (t=0; t<1000; t++) {
y = f(t)
}
그리고 실시간 코드에서 사용하는 것이 나쁘다고 생각하는 것 :
for (t=0; t<1000; t++) {
y = A(B)(t);
}
그리고 스택 메모리가 클로저에 사용될 가능성이 있다고 생각하는 곳 :
freq = 220;
A = 2;
for (t=0; t<1000; t++) {
y = [=](int t){ return sin(t*freq)*A; }
}
후자의 경우 루프가 반복 될 때마다 클로저가 생성되지만 이전 예제와 달리 함수 호출과 같으므로 힙 할당이 이루어지지 않기 때문에 저렴합니다. 또한 컴파일러가 클로저를 "리프트"하고 인라인 최적화를 수행 할 수 있는지 궁금합니다.
이 올바른지? 감사합니다.
operator()
. 수행 할 "리프팅"은 없습니다. 람다는 특별한 것이 아닙니다. 그것들은 지역 함수 객체의 약자 일뿐입니다.