JIT\ 를 인식하는 프로파일러 =========================== 목표: PyPy JIT을 인식하고, 어느 루프에서 얼마만큼의 시간 비율이 소비되었는지 보여주는 프로파일러를 만드는 것입니다. 장기 목표: 프로파일러가 수집한 데이터를 jitviewer\ 와 통합합니다. 이 아이디어는 루프(loop)나 브리지(bridge)에 진입하고 빠져나갈 때마다 PYPYLOG에 이벤트를 기록하는 것입니다. 예상 출력 --------- [100] {jit-profile-enter loop1 # 예: 진입 브릿지 [101] jit-profile-enter} ... [200] {jit-profile-enter loop0 # loop1에서 loop0로 JUMP [201] jit-profile-enter} ... [500] {jit-profile-exit loop0 # 예: 가드(guard) 실패로 인해 [501] jit-profile-exit} 이 예제에서 loop1에서의 탈출은 암시적인데, loop0으로 진입하고 있기 때문입니다. 따라서 진입 브리지에서 200-100=100틱을, 실제 루프에서 500-200=300틱을 소비했습니다. "내부(inner)" 브리지는 어떻게 처리할 것인가? -------------------------------------------- "내부 브리지(Inner bridges)"는 자신이 시작된 루프로 다시 점프하는 브리지를 말합니다. 이를 처리하는 방법에는 두 가지가 있습니다: 1. 이들을 무시합니다: 루프에 진입할 때는 기록하지만, 컴파일된 내부 브리지로 점프할 때는 기록하지 않습니다. 종료 이벤트는 컴파일되지 않은 가드(guard) 실패나 다른 루프로의 JUMP인 경우에만 기록됩니다. 2. 우리는 각 내부 브리지(bridge)의 진입/종료를 기록합니다 해결책 (2)의 단점은 매 반복마다 브리지를 타는 특정 루프들이 있다는 것입니다. 따라서 이 경우 방대한 수의 이벤트를 기록하게 되어, 상당한 오버헤드가 추가될 수 있고 결국 프로파일링된 데이터를 쓸모없게 만들 수 있습니다. 루프 진입/탈출 감지 ------------------- 참여 방법: - 트레이싱/컴파일 직후 - 인터프리터로부터, 루프가 이미 컴파일되어 있다면 - 다른 루프로부터, JUMP 연산\ 을 통해 - 핫 가드(guard) 실패로부터 (해결책을 선택하는 경우 우리가 무시하는) (1) 위 참조) - XXX: 빠진 것이 있나요? 종료 방법: - 가드(guard) 실패\ (블랙홀 진입) - 가드(guard) 실패(브릿지로 점프) (해결책 (1)의 경우 무시됨) - 다른 루프로 점프 - XXX: 제가 놓친 것이 있을까요? call_assembler에 대해: 처음에는 call_assembler를 그냥 무시해야 한다고 생각합니다. 호출 내부에서 소요된 시간은 그것을 호출하는 루프에 귀속될 것입니다.