글쎄, 나는 놀기를 거부 할 수 없었다. 저는 단 정밀도와 배정도를 위해 pairwise 유클리드 거리를 구현하는 pdistc
이라는 Matlab mex C file을 만들었습니다. 내 컴퓨터에서 Matlab R2012b 및 R2015a를 사용하면 큰 입력 (예 : 60,000 x 300)의 경우 pdist
(기본 도우미도우미 기능)보다 20 % 더 빨라 20 –입니다.
지적했듯이이 문제는 근본적으로 메모리에 국한되어 있으므로 많은 것을 요구하고 있습니다. 내 mex C 코드는 출력에 필요한 최소한의 메모리를 사용합니다. 메모리 사용량을 pdist
의 메모리 사용량과 비교할 때 두 메모리가 거의 같아 보입니다. 즉, pdist
은 많은 추가 메모리를 사용하지 않습니다. 메모리 문제는 메모리가 많아서 pdist
(큰 배열을 제거하려면 clear
을 사용할 수 있습니까?)을 호출하기 전에 사용했거나 작은 하드웨어에서 큰 계산 문제를 해결하려고하기 때문에 발생했을 수 있습니다.
따라서 pdistc
함수는 전체 메모리를 절약 할 수는 없지만 내장 된 다른 기능을 사용할 수는 있습니다. 전체 쌍 거리 벡터의 덩어리를 계산할 수 있습니다. 이런 식으로 뭔가 :
m = 6e3;
n = 3e2;
X = rand(m,n);
sz = m*(m-1)/2;
for i = 1:m:sz-m
D = pdistc(X', i, i+m); % mex C function, X is transposed relative to pdist
... % Process chunk of pairwise distances
end
이 상당히 느린 (10 회 정도) 내 C 코드의이 부분이 잘 최적화되어 있지 않습니다,하지만 당신은 필요하지 않습니다 가정 훨씬 적은 메모리 사용 –을 허용합니다 한 번에 전체 배열. pdist
(또는 pdistc
)을 사용하면 모두가 아닌 X
의 하위 집합을 직접 전달한 루프를 만들어 훨씬 더 효율적으로 동일한 작업을 수행 할 수 있습니다.
64 비트 Intel Mac을 사용하는 경우 .mexmaci64
바이너리가 포함되어 있으므로 컴파일 할 필요가 없지만 컴퓨터 코드를 컴파일하는 방법을 알아야합니다. 나는 너를 도울 수 없어.컴파일 할 수 없거나 직접 코드를 편집하여 해결해야하는 호환성 문제가있을 수 있습니다. 버그가 있고 코드가 Matlab을 파괴 할 수도 있습니다. 또한 기계 엡실론 (eps
)의 범위에서 차이가있는 pdist
에 대해 약간 다른 출력이 나올 수 있습니다. pdist
은 큰 입력 및 기타 숫자 문제로 인한 오버플로를 피하기 위해 멋진 일을 할 수도 있고하지 않을 수도 있지만 내 코드는 그렇지 않습니다.
또한 간단한 pure Matlab implementation을 만들었습니다. 그것은 mex 코드보다 훨씬 느리지 만 순진한 구현이나 pdist
에있는 코드보다 빠릅니다.
모든 파일 can be found here. ZIP 아카이브에는 모든 파일이 포함됩니다. BSD 라이센스입니다. 자유롭게 느껴보십시오 (BLAS 호출과 OpenMP를 C 코드로 사용해 보았습니다. – 포인터 마술이나 GPU/OpenCL로 속도를 높일 수 있습니다). 나는 그것이 당신이나 다른 누군가에게 도움이되기를 바랍니다. 다음 내 시스템에서
이것은 결코 간단하지 않을 것입니다. 계산할 결과는 ~ 2e9 개이며, 각각 300 개의 곱셈과 600 개의 덧셈/뺄셈이 필요합니다. 따라서 총 작업량은 약 2e12입니다. –
즉, 충분히 최적화 된 코드를 사용하면 6-7 시간보다 현저하게 더 나아질 수 있어야합니다. –
@OliCharlesworth - 알고있는 유일한 방법은 사용중인 컴퓨터에 대해 더 많이 알고있는 것입니다. 얼마나 많은 RAM 이요? –