파이썬 (및 기타 동적 언어)의 의미 기능이 속도 저하에 기여합니까?


26

나는 파이썬을 잘 모른다. 동적 언어 (La Python, Lua, Scheme, Perl, Ruby 등)의 정확한 기능이 구현 속도를 늦추는 것을 더 정확하게 이해하려고합니다.

실제로 Lua 5.3 메타 테이블 기계 는 직관적으로 Lua를 느리게 만들지 만 실제로는 Lua가 상당히 빠르다는 소문이 있습니다 (Python보다 빠름).

또한 현재 프로세서에서 메모리가 원시 계산보다 훨씬 느리다는 직관 (아마도 잘못된 것)이 있습니다 (캐시 미스가있는 메모리 액세스에는 수백 개의 산술 연산과 같은 시간이 필요함), 동적 유형 검사 (a la if (value->type != INTEGER_TAG) return;in C 어휘)는 꽤 빨리 실행될 수 있습니다.

물론 스탈린 구성표 구현 과 같은 전체 프로그램 분석 은 번역기가 빠르게 실행될 때 동적 언어 구현을 만들 수 있지만 처음에는 전체 프로그램 분석기를 설계 할 시간이 없다고 가정합시다.

(저는 MELT 모니터 에서 동적 언어를 디자인하고 있으며 일부는 C로 번역됩니다)



1
Lua Performance Tips (루아 성능 팁 )-일부 Lua 프로그램이 왜 느린 지와 수정 방법을 설명합니다.
Robert Harvey

답변:


24

파이썬 (및 기타 동적 언어)의 의미 기능이 속도 저하에 기여합니까?

없음

언어 구현의 성능은 언어 기능이 아니라 돈, 자원 및 박사 학위 논문의 기능입니다. 본인 는 Smalltalk보다 훨씬 더 동적이고 Python, Ruby, ECMAScript 또는 Lua보다 약간 더 동적이며, 기존의 모든 Lisp 및 Smalltalk VM보다 성능이 뛰어난 VM이있었습니다 (실제로 Self 배포는 Self로 작성된 작은 Smalltalk 인터프리터와 함께 제공됨) 심지어 기존의 대부분의 스몰 토크 VM보다 빠르며 C ++ 구현보다 훨씬 빠르며 때로는 더 빠릅니다.

그 후 썬은 셀프 펀딩을 중단했고 IBM, Microsoft, Intel, Co.는 C ++에 대한 펀딩을 시작했고 추세는 역전되었습니다. Self 개발자는 Sun을 떠나 자신의 회사를 설립했습니다. 여기에서 Self VM을 위해 개발 된 기술을 사용하여 가장 빠른 Smalltalk VM (Animorphic VM) 중 하나를 구축 한 다음 Sun은 해당 회사를 다시 사들였습니다. Smalltalk VM은 "HotSpot JVM"이라는 이름으로 더 잘 알려져 있습니다. 아이러니하게도 Java 프로그래머는 동적 언어를 "느린"것으로 생각합니다. 자바동적 언어 기술을 채택 할 때까지 느 렸습니다. (예, 맞습니다 : HotSpot JVM은 본질적으로 스몰 토크 VM입니다. 바이트 코드 검증기는 많은 유형 검사를 수행하지만 일단 바이트 코드가 검증 자, VM, 특히 옵티 마이저 및 JIT에 의해 승인되면 실제로 수행하지 않습니다. 정적 유형에 관심이 많습니다!)

CPython은 동적 컴파일 (JIT), 동적 최적화, 추론 적 인라이닝, 적응 형 최적화, 동적 역 최적화, 동적 유형 피드백 / 추론과 같이 동적 언어 (또는 동적 디스패치)를 빠르게 만드는 많은 작업을 수행하지 않습니다. 거의 전체 코어 및 표준 라이브러리가 C로 작성된다는 문제가 있습니다. 즉, Python 100x를 갑자기 더 빠르게 만들더라도 95 %의 코드와 같은 코드가 실행되기 때문에 많은 도움이되지 않습니다. 파이썬 프로그램은 파이썬이 아닌 C입니다. 모든 것이 파이썬으로 작성된 경우, 중간 정도의 속도 향상조차도 알고리즘이 빨라지고 핵심 데이터 구조가 빨라지는 효과를 눈에 띄게 만들지 만 물론 핵심 데이터 구조는 알고리즘과 핵심 알고리즘 및 핵심 데이터에도 사용됩니다 구조는 다른 곳에서 사용됩니다.

오늘날의 시스템에는 메모리 관리 OO 언어 (동적이든 아니든)에 악명이 나쁜 것으로 몇 가지 있습니다. 가상 메모리 및 메모리 보호는 가비지 수집 성능, 특히 시스템 성능의 킬러가 될 수 있습니다. 메모리에 안전한 언어에서는 전혀 필요하지 않습니다. 언어에서 메모리 액세스가 시작되지 않은 경우 왜 불법 메모리 액세스로부터 보호해야합니까? 아줄은 현대적인 강력한 MMU를 (인텔 네 할렘과 새, 그리고 AMD의 상당)를 사용하여 알아 낸 도움말 을 방해하는 대신 가비지 수집을하지만,이 CPU가 지원하는 경우에도, 주류 OS 년대의 현재 메모리 서브 시스템은 강력한 충분하지 않습니다 아줄의 JVM이 실제로 베어 메탈 가상화 실행됩니다 이유입니다 (이 허용하는 외에 그 안에 있지 않은 OS).

Singularity OS 프로젝트에서 Microsoft는 프로세스 분리를 ​​위해 유형 시스템 대신 MMU 보호를 사용할 때 시스템 성능에 ~ 30 %의 영향을 측정했습니다.

Azul이 특수한 Java CPU를 구축 할 때 주목 한 또 다른 사실은 현대 주류 CPU가 캐시 누락 비용을 줄이려고 할 때 완전히 잘못된 것에 초점을 맞추고 있다는 것입니다. 그들은 브랜치 예측, 메모리 프리 페칭, 등등. 그러나 다형성 OO 프로그램에서 액세스 패턴은 기본적으로 의사 난수이며 예측할 것이 없습니다. 따라서 모든 트랜지스터가 낭비되고 대신해야 할 일은 모든 개별 캐시 미스의 비용을 줄이는 것입니다. (총 비용은 #misses * 비용이며, 주류는 첫 번째 하락을, Azul은 두 번째 하락을 시도합니다.) Azul의 Java Compute Accelerator는 비행 중에 20000 개의 동시 캐시 누락이있을 수 있으며 여전히 진행될 수 있습니다.

Azul은 시작했을 때 기성품 I / O 구성 요소를 가져 와서 고유 한 특수 CPU 코어를 설계 할 것이라고 생각 했지만 실제로 필요한 것은 정반대의 것이 었 습니다 . 선반 3 주소 RISC 코어 및 자체 메모리 컨트롤러, MMU 및 캐시 하위 시스템을 설계했습니다.

tl; dr : 파이썬의 "느린 점"은 언어의 속성이 아니라 a) 순진한 (기본) 구현 및 b) 최신 CPU 및 OS가 C를 빠르게 실행하도록 특별히 설계되었다는 사실과 그 기능 C는 파이썬 성능을 돕거나 (캐시) 또는 적극적으로 아프게하지 않습니다 (가상 메모리).

그리고 당신은 여기에 동적 임시 다형성을 가진 거의 모든 메모리 관리 언어를 삽입 할 수 있습니다. 효율적인 구현의 문제에 관해서는, 파이썬과 자바조차도 거의 "동일한 언어"입니다.


Azul에 대한 링크 또는 참조가 있습니까?
Basile Starynkevitch

4
언어의 의미 가 효율적으로 구현하는 데 아무런 영향을 미치지 않는다는 데 동의하지 않습니다 . 그렇습니다. 일급 최적화 및 분석을 통한 우수한 JIT 구현 은 언어의 성능을 크게 향상시킬 수 있지만 결국 병목 현상이 발생하는 의미론의 특정 측면이 있습니다. 포인터의 엄격한 별칭 지정에 대한 C의 요구 사항이나 목록 작업이 원자 적으로 수행되어야하는 Python의 요구 사항인지 여부에 관계없이 불가피하게 일부 응용 프로그램의 성능을 손상시키는 특정 의미 결정이 있습니다.
Jules

1
제쳐두고 ... 특이점에 대한 30 % 개선에 대한 참조가 있습니까? 나는 수년 동안 언어 기반 보호 OS를 옹호 해 왔지만 이전에는 그 모습을 본 적이 없었으며, 놀랍게도 발견했습니다 (과거에 보았던 그림이 10 %에 가깝습니다). 그들은 많은 개선을 얻었습니다 ...
Jules

5
@MasonWheeler : 거기에는 엉뚱한 파이썬 구현이 있기 때문에. 파이썬 구현자는 IBM, Sun, Oracle, Google 및 Co.가 J9, JRockit, HotSpot 및 Co에 소비 한 돈, 사람, 연구 및 자원의 작은 부분조차도 사용하지 않았습니다. 오라클이 가비지 수집기에만 소비하는 인력을 확보하십시오. IBM은 Eclipse OMR (J9에서 추출한 구성 요소 화 된 오픈 소스 VM 프레임 워크)을 기반으로하는 Python 구현을 연구하고 있으며, 성능이 J9 정도에 달할 것이라고 확신합니다.
Jörg W Mittag

2
Fortran 은 엄격한 앨리어싱을 시행하므로 최적화 프로그램이 더욱 공격적 일 수 있으므로 레코드의 경우 C가 Fortran과 비교할 때 수치 작업 이 느립니다 .
Michael Shopsin

8

파이썬의 현재 구현 (현대 자바 스크립트 구현과 같이 다른 동적 언어에 의해 수행되는 많은 최적화가 부족하고 Lua가 지적했듯이 Lua)이 대부분의 문제의 원인이지만, 의미 론적 문제가 있습니다. 구현이 적어도 특정 분야에서 다른 언어와 경쟁하기가 어렵습니다. 특히 고려해야 할 가치가있는 것들 :

  • 언어 정의에는 원자 및 원자 목록이 필요합니다. 즉, JIT 컴파일러가 목록 객체에 대한 참조가 현재 스레드를 이스케이프하지 않았 음을 증명할 수없는 경우 (많은 경우 어렵고 일반적인 경우에는 불가능한 분석) 객체에 대한 액세스가 직렬화되어야합니다 (예 : 잠금을 통해). CPython 구현은 악명 높은 "글로벌 인터프리터 잠금"을 사용하여이 문제를 해결합니다.이 기능은 멀티 스레드 기술을 사용하여 다중 처리 환경에서 Python 코드를 효과적으로 사용하지 못하도록하며 다른 솔루션도 가능하지만 성능 문제가 있습니다.

  • 파이썬에는 값 객체의 사용을 지정하는 메커니즘이 없습니다. 모든 것이 참조로 처리되어 반드시 필요하지 않은 곳에 간접적 인 지시를 추가합니다. JIT 컴파일러가 경우에 따라 값 객체를 추론하고이를 자동으로 최적화 할 수는 있지만 일반적으로 그렇게 할 수는 없으므로 최적화가 가능하도록 신중하게 작성되지 않은 코드 (일부 검은 기술) 고통받을 것이다.

  • Python에는 eval함수 가 있습니다. 즉, JIT 컴파일러는 eval한 번만 사용되는 한 전체 프로그램 분석을 수행하더라도 발생하지 않는 조치에 대해 가정 할 수 없습니다 . 예를 들어, 파이썬 컴파일러는 클래스에 서브 클래스가 없다고 가정 할 수 없으므로 메소드 호출은 나중에 호출을 통해 무효화 될 수 있기 때문에 메소드 호출을 고안합니다 eval. 대신 네이티브 컴파일 된 코드에 의해 만들어진 가정이 해당 코드를 실행하기 전에 무효화되지 않도록 동적 유형 검사를 수행해야합니다.


3
후자의 포인트는 eval재 컴파일 및 / 또는 최적화 해제 를 트리거함으로써 완화 될 수 있습니다 .
Jörg W Mittag

4
그건 그렇고, 그것은 파이썬에만 고유하지 않습니다. Java (또는 JVM)에는 동적 코드로드 및 동적 링크가 있으므로 클래스 계층 분석은 Halting 문제를 해결하는 것과 같습니다. 그러나 HotSpot은 행복하게 다형성 메소드를 인라인으로 인라인하고 클래스 계층 구조의 무언가가 변경되면 다시 인라인합니다.
Jörg W Mittag
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.