मुझे ArrayFire बहुत तेज होने के लिए मिला है और छवि प्रसंस्करण के लिए ओपनसीवी में GPU कर्नेल के बजाय इसका उपयोग शुरू कर दिया है। यहां some benchmarks हैं जिन्हें मैंने ओरेसीएफवी में ऐरेफायर (लिबजैकेट नामक एक अलग इंटरफेस में इस्तेमाल किया) की तुलना में पाया और यह मेरे बेंचमार्किंग में भी सच रहा है कि ओरेसीएफ में जीपीयू कार्यों की तुलना में ऐरेफायर 2-4X तेज है। जो मैंने सुना है, एनवीआईडीआईए ने ओपनसीवी में जीपीयू कर्नेल नहीं लिखे थे, लेकिन उन लोगों को अनुबंधित किया, जो कि इतने धीमे हो सकते हैं। चूंकि मैं केवल 1 जीपीयू का उपयोग कर रहा हूं, इसलिए मैं ऐरेफ़ीयर का मुफ्त में उपयोग कर सकता हूं।
अद्यतन, @Alex: द्वारा पोस्ट किए गए नए MATLAB कोड को देखते हुए मैंने अपने सिस्टम पर इस कोड का बेंचमार्क चलाया। मुझे लगता है कि समांतर कंप्यूटिंग टूलबॉक्स gpuArray CPU से धीमा है, लेकिन जैकेट और ArrayFire किक बट। HW चश्मा हैं:
CPU के
Intel(R) Xeon(R) CPU X5660 @ 2.80GHz
NVIDIA Tesla M2090
परिणाम पैरलल कंप्यूटिंग उपकरण बॉक्स gpuArray (पूरी तरह से गरम) का उपयोग कर GPU बनाम। सीपीयू पीसीटी gpuArray की तुलना में तेजी है: जैकेट (पूरी तरह से गरम) का उपयोग कर सीपीयू GPU बनाम की
>> tic; sqEuclideanDist(gpuArray(rand(1581,3)),gpuArray(rand(189,3))); toc;
Elapsed time is 0.006859 seconds.
>> tic; sqEuclideanDist(rand(1581,3),rand(189,3)); toc;
Elapsed time is 0.005712 seconds.
परिणाम। जैकेट पीसीटी gpuArray 3 द्वारा धड़कता है।7X और 3X
>> tic; sqEuclideanDist(gdouble(rand(1581,3)),gdouble(rand(189,3))); toc;
Elapsed time is 0.001876 seconds.
यहाँ से सीपीयू धड़कता संशोधित कोड है कि है कि आसानी से आप चलाने के सभी है:
function K = sqEuclideanDist(P,Q)
% Vectorized method to compute pairwise squared Euclidean distance on GPU
% Returns K(i,j) = (P(i,:) - Q(j,:))'*(P(i,:) - Q(j,:))
[nP, d] = size(P);
[nQ, d] = size(Q);
pmag = sum(P .* P, 2);
qmag = sum(Q .* Q, 2);
K = ones(nP,1)*qmag' + pmag*ones(1,nQ) - 2*P*Q';
end
जैकेट GPU पर समर्थन BSXFUN करता है, और यह कुछ हद तक गति में सुधार करता है :
>> tic; sqEuclideanDist(gdouble(rand(1581,3)),gdouble(rand(189,3))); toc;
Elapsed time is 0.001420 seconds.
ध्यान दें कि आकार यहां इस्तेमाल किया, बहुत छोटे हैं, इसलिए अधिकांश CUDA कोड है कि इन छोटे आकार पर चलाने के लिए प्रयास करता है खराब प्रदर्शन की संभावना है। यही कारण है कि मैं एक्सेलेरियस की सामग्री का उपयोग करना पसंद करता हूं, क्योंकि उन लोगों ने पीपीटी जीपीयूएरे, थ्रस्ट, ओपनसीवी के विपरीत जीपीयू से बिल्ली को अनुकूलित किया है, जिनमें से प्रत्येक मैंने अतीत में कोशिश की है।
यहाँ ArrayFire नि: शुल्क सी ++ परिणाम है:
Time: 0.0003577 seconds
Speedups: 19.2X faster than PCT gpuArray, 16X faster than the CPU, 5.2X faster
than Jacket in MATLAB original version, 4X faster than Jacket in MATLAB using
BSXFUN
यहाँ ArrayFire कोड मैं इस के लिए लिखा था है:
static array SqEuclideanDist(array P, array Q)
{
// 0 based indexing
array pmag = sum(P * P, 1);
array qmag = sum(Q * Q, 1);
int np = P.dims(0);
int nq = Q.dims(0);
array K = tile(qmag.T(), np, 1) * tile(pmag, 1, nq) - 2 * matmul(P, Q.T());
return K;
}
int main(int argc, char **argv)
{
double *P_cpu = new double[1581 * 3];
double *Q_cpu = new double[189 * 3];
array P = array(1581, 3, P_cpu);
array Q = array(189 , 3, Q_cpu);
af::sync();
int iter = 1000;
timer::tic();
for (int i = 0; i < iter; i++) {
array K = SqEuclideanDist(P, Q);
af::eval(K);
}
af::sync();
printf("Time taken: %2.4lfms\n", (1000 * timer::toc())/iter);
delete[] P_cpu;
delete[] Q_cpu;
}
विशेष रूप से क्या काम करता है आप का उपयोग पर विचार कर रहे हैं? –
बेसिक मैट्रिक्स सामान। gpu :: कम करें, gpu :: गुणा करें (प्रति तत्व मैट्रिक्स गुणा)। इसके अलावा, मैट्रिक्स गुणा, मैट्रिक्स eigenvalues और eigenvectors, मैट्रिक्स transpose खोज। – Alexey
@Alex - सभी साधारण मैट्रिक्स ओप सीधे एनवीडिया (जोर?) लाइब्रेरी का उपयोग करते हैं, इसलिए बहुत अच्छी तरह से अनुकूलित –