2011-01-27 8 views

답변

5

편집 : 혼합 PyMem_MallocPyObject_Malloc 수정; 두 가지 다른 호출입니다. 없이

PYMALLOC_DEBUG 매크로, PyMem_Malloc 한 특별한 경우를 가지고, libc의의 malloc()의 별칭 활성화 : malloc에 ​​(zero_bytes)는 NULL 값을 반환하거나 인상하는 반면, 비 NULL 포인터를 반환 0 바이트를 할당 할 수 PyMem_Malloc를 호출 시스템 오류 (source code reference) :

/* malloc. nbytes == 0은 이 다른 모든 현재 활성 포인터에서 *이라는 고유하지 않은 포인터를 반환하려고 시도합니다. 이것은 가능하지 않을 수 있습니다.

무료 플랫폼의 malloc/realloc을/ 은 calloc /에 호출로 PyMem_에 전화를 혼용하지 마십시오 :

*/

또한, 자문 pymem.h header file에 참고가있다.예를 들어, Windows에서 다른 DLL은 다른 힙을 사용하여 끝날 수 있으며 PyMem_Malloc을 사용하면 을 파이썬 DLL에서 사용하는 힙에서 가져옵니다. 재해가 될 수 있습니다. 무료로() '직접 해당 사용자의 내선 번호를 입력하십시오. 대신 PyMem_Free를 사용하면 파이썬이 메모리를 적절한 힙으로 반환 할 수 있습니다. 또 다른 예를 들어, PYMALLOC_DEBUG 모드에서 파이썬은 동적 메모리 블록에 추가 디버깅 정보를 추가 특별한 디버깅 래퍼의 모든 PyMem_ 및 PyObject_ 메모리 기능에 대한 모든 호출을 래핑합니다. 시스템 루틴은 그걸로 무엇을 해야할지 전혀 모르며, 파이썬 래퍼는 무엇을 해야할지 전혀 모른다. 원시 블록은 에 의해 직접 시스템 루틴을 얻는다.

: 파이썬 프로그램을 실행하는 동안 다음

, PyMem_Malloc PyObject_Malloc 내부의 파이썬 특정 튜닝이있다, 함수 100*234, str(100) 또는 10 + 4j처럼, C의 확장에 있지만 모든 동적 할당을 위해뿐만 아니라 사용

>>> id(10 + 4j) 
139721697591440 
>>> id(10 + 4j) 
139721697591504 
>>> id(10 + 4j) 
139721697591440 

이전 complex() 인스턴스는 전용 풀에 할당 된 작은 개체입니다. 그것은 각각의 블록 사이즈에 대해 하나의 기존 풀, 풀로부터 블록의 8 바이트 정렬을 완료 이후 PyMem_Malloc PyObject_Malloc

작은 개체 (< 256 바이트)의 할당은 매우 효율적이다. 더 큰 할당을위한 페이지 및 아레나 블록도 있습니다.

source code에이 의견은 PyObject_Malloc 호출이 최적화 방법에 대해 설명합니다

/* 
* The basic blocks are ordered by decreasing execution frequency, 
* which minimizes the number of jumps in the most common cases, 
* improves branching prediction and instruction scheduling (small 
* block allocations typically result in a couple of instructions). 
* Unless the optimizer reorders everything, being too smart... 
*/ 

수영장, 페이지 및 아레나스는 장기 실행 파이썬 프로그램의 external memory fragmentation을 줄이기위한 최적화되어 있습니다.

파이썬의 메모리 내부에 대한 자세한 내용은 the source code을 확인하십시오.

+0

네이티브 할당자는 이미 매우 최적화되어 있습니다. 이것은 확장 모듈에 아무런 영향을 미치지 않습니다. 어떤 것이라도 느려지는 추가 오버 헤드 일뿐입니다. –

+0

@Glenn 당신은 그것을지지하기 위해 어려운 번호를 사용합니까? 문서는 상당히 광범위하고 자세하게 묘사되어 "느려지는 오버 헤드"가됩니다. – vz0

+0

필자는 경험과 상식이 있습니다. 시스템 할당자는 전체 시스템의 속도에 영향을 미치므로이를 최적화하는 데 많은 노력이 필요합니다. 파이썬이 저수준 파이썬 코어의 특별한 경우뿐만 아니라 확장 모듈 사용을 위해 향상되었다고 주장한다면, 그것이 백업의 주장이다. –

1

MATLAB .mex 함수를 작성한 경험으로 볼 때 malloc을 사용하는지 여부를 결정하는 가장 큰 요인은 이식성입니다. 내부 c 데이터 유형 (필요한 파이썬 객체 상호 작용이 없으므로 malloc을 사용하여 문제가 없음)을 사용하여 유용한 함수를로드하는 헤더 파일을 가지고 있고, 헤더 파일을 다른 코드베이스로 이식하려는 것을 갑자기 알게되었다고 가정 해보십시오. 파이썬과는 전혀 관계가 없습니다 (아마도 C 언어로 작성된 프로젝트 일 것입니다). malloc을 사용하면 훨씬 더 이식성있는 솔루션이 될 것입니다.

순수한 Python 확장 코드인데 초기 반응은 원시 c 함수가 더 빨리 수행 될 것으로 기대하는 것입니다. 나는 이것을 뒷받침 할 어떤 증거도 가지고 있지 않다.

+2

네이티브 C 함수가 더 잘 수행되기를 기대합니다. 것은 그들이 모두 네이티브 C 함수입니다. :-) –

+1

글쎄요 ... 그들은 훌륭한 기술이라고 생각합니다. 나는 C의 네이티브 메모리 할당 시스템이 파이썬의 메모리 할당 시스템을 위해 구현 된 네이티브 C보다 더 빠를 것이라고 기대한다고 더 많은 것을 추측했다 : P – William

+2

나는 malloc과 PyMem_Malloc. 내 벤치 마크에서이 둘 사이의 성능 차이가 무시되었습니다. PyMem_Malloc은 더 빠르지 만 차이점이 통계적으로 적절하다고 생각하지 않습니다. 물론 YMMV. – casevh

6

확장이 malloc 또는 다른 시스템 할당자를 사용하여 메모리를 할당하는 것은 완벽하다. 이것은 많은 종류의 모듈에서 정상적이고 필연적입니다. 파이썬에 관해 전혀 모르는 다른 라이브러리를 감싸는 대부분의 모듈은 그 라이브러리 내에서 발생했을 때 네이티브 할당을 유발할 것입니다. (어떤 라이브러리는 이것을 방지 할 수 있도록 할당을 제어 할 수 있지만 대부분 금지하지는 않습니다.)

PyMem_Malloc을 사용할 때 심각한 단점이 있습니다. PyMem_Malloc을 사용할 때 GIL을 유지해야합니다. 네이티브 라이브러리는 CPU 집약적 인 계산을하거나 I/O와 같이 차단할 수있는 호출을 할 때 GIL을 해제하려고합니다. 할당 전에 GIL을 잠글 필요가있어 매우 불편 함과 성능 문제 사이에있을 수 있습니다.

메모리 할당을위한 파이썬의 래퍼를 사용하면 파이썬의 메모리 디버깅 코드를 사용할 수 있습니다. 그러나 Valgrind와 같은 도구를 사용하면 실제 가치가 의심 스럽습니다.

API에 필요하면 이러한 기능을 사용해야합니다. 예를 들어 API에 이러한 함수로 할당해야하는 포인터가 전달되면 API를 통해 해제 할 수 있습니다. 그것들을 사용하는 것과 같은 명백한 이유가 없다면 나는 정상적인 할당을 계속한다.

관련 문제