व्यापक रूप से, GPU पर तेजी से चलने वाले एल्गोरिदम वे हैं जहां आप कई अलग-अलग डेटा बिंदुओं पर एक ही प्रकार के निर्देश कर रहे हैं।
इसका उदाहरण देने के लिए एक आसान उदाहरण मैट्रिक्स गुणा के साथ है।
मान लीजिए हम मैट्रिक्स की गणना कर रहे हैं
ए × बी = सी
एक साधारण सीपीयू एल्गोरिथ्म कुछ इस तरह दिख सकता है
// सी = 0 से शुरू
for (int i = 0; i < C_Width; i++)
{
for (int j = 0; j < C_Height; j++)
{
for (int k = 0; k < A_Width; k++)
{
for (int l = 0; l < B_Height; l++)
{
C[j, i] += A[j, k] * B[l, i];
}
}
}
}
यहां देखने वाली महत्वपूर्ण बात यह है कि लूप के लिए बहुत सारे नेस्टेड हैं और प्रत्येक चरण को एक के बाद एक निष्पादित करना होगा।
इसका एक चित्र देखें
ध्यान दें कि C के प्रत्येक तत्व की गणना किसी अन्य तत्व पर निर्भर नहीं करती है। इसलिए यह मायने नहीं रखता कि गणना किस क्रम में की जाती है।
इसलिए GPU पर, ये ऑपरेशन समवर्ती रूप से किए जा सकते हैं।
मैट्रिक्स गुणा को शांत करने के लिए एक GPU कर्नेल कुछ इस तरह दिखाई देगा
__kernel void Multiply
(
__global float * A,
__global float * B,
__global float * C
)
{
const int x = get_global_id(0);
const int y = get_global_id(1);
for (int k = 0; k < A_Width; k++)
{
for (int l = 0; l < B_Height; l++)
{
C[x, y] += A[x, k] * B[l, y];
}
}
}
इस कर्नेल में केवल दो आंतरिक छोरों के लिए है। इस काम को GPU पर भेजने वाला एक प्रोग्राम GPU को C. में प्रत्येक डेटा बिंदु के लिए इस कर्नेल को निष्पादित करने के लिए बताएगा। GPU इनमें से प्रत्येक निर्देश को कई थ्रेड्स पर समवर्ती रूप से करेगा। पुरानी कहावत की तरह "सस्ता बाय द दर्जनों" जीपीयू को कई बार एक ही काम तेजी से करने के लिए डिज़ाइन किया गया है।
हालाँकि कुछ एल्गोरिदम हैं जो GPU को धीमा कर देंगे। कुछ GPU के लिए अच्छी तरह से अनुकूल नहीं हैं।
उदाहरण के लिए, डेटा निर्भरताएँ थीं, यानी: पिछले तत्वों पर निर्भर C के प्रत्येक तत्व की गणना। प्रोग्रामर को प्रत्येक पिछले गणना समाप्त होने की प्रतीक्षा करने के लिए कर्नेल में एक बाधा डालनी होगी। यह एक बड़ी धीमी गति होगी।
इसके अलावा, एल्गोरिदम जिसमें बहुत सारे ब्रांचिंग लॉजिक हैं:
__kernel Foo()
{
if (somecondition)
{
do something
}
else
{
do something completely different
}
}
GPU पर धीमी गति से चलाने के लिए क्योंकि GPU अब प्रत्येक थ्रेड में एक ही काम नहीं कर रहा है।
यह एक सरलीकृत स्पष्टीकरण है क्योंकि विचार करने के लिए कई अन्य कारक हैं। उदाहरण के लिए, सीपीयू और जीपीयू के बीच डेटा भेजने में भी समय लगता है। कभी-कभी सीपीयू पर तेज होने पर भी यह GPU पर गणना करने के लायक होता है, बस अतिरिक्त भेजने के समय (और इसके विपरीत) से बचने के लिए।
इसके अलावा कई आधुनिक सीपीयू अब हाइपरथ्रेडेड मल्टीकोर प्रोसेसर के साथ ही कंफर्टबिलिटी का समर्थन करते हैं।
GPU भी पुनरावृत्ति के लिए इतना अच्छा नहीं लगता है, यहाँ देखें जो शायद QR एल्गोरिथ्म के साथ कुछ समस्याओं की व्याख्या करता है। मेरा मानना है कि किसी के पास कुछ पुनरावर्ती डेटा निर्भरताएं हैं।