Geniş anlamda, GPU'da daha hızlı çalışan algoritmalar, birçok farklı veri noktasında aynı tür talimatlar yaptığınız algoritmalardır.
Bunu açıklamak için kolay bir örnek matris çarpımıdır.
Matris hesaplamasını yaptığımızı varsayalım
A × B = C
Basit bir CPU algoritması şuna benzeyebilir
// C = 0 ile başlayan
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];
}
}
}
}
Burada görülmesi gereken en önemli şey, döngüler için çok fazla iç içe geçmiş olması ve her adımın birbiri ardına gerçekleştirilmesi gerektiğidir.
Bunun bir şemasına bakın
Her bir C elemanının hesaplanmasının diğer elemanlardan hiçbirine bağlı olmadığına dikkat edin. Bu nedenle, hesaplamaların hangi sırada yapıldığı önemli değildir.
GPU'da, bu işlemler aynı anda yapılabilir.
Matris çarpımını hesaplamak için bir GPU çekirdeği,
__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];
}
}
}
Bu çekirdek döngüler için sadece iki iç kısma sahiptir. Bu işi GPU'ya gönderen bir program, GPU'ya C'deki her veri noktası için bu çekirdeği yürütmesini söyler. GPU, bu talimatların her birini aynı anda birçok iş parçacığında yapacaktır. Tıpkı eski "Düzine tarafından daha ucuz" deyimi gibi GPU'lar aynı şeyi birçok kez daha hızlı yapmak üzere tasarlanmıştır.
Bununla birlikte, GPU'yu yavaşlatacak bazı algoritmalar vardır. Bazıları GPU için uygun değildir.
Örneğin, veri bağımlılıkları varsa, yani: C'nin her bir elemanının, önceki elemanlara bağlı olarak hesaplandığını hayal edin. Programcı, önceki hesaplamaların tamamlanmasını beklemek için çekirdeğe bir bariyer koymak zorunda kalacaktı. Bu büyük bir yavaşlama olurdu.
Ayrıca, çok fazla dallanma mantığına sahip algoritmalar yani:
__kernel Foo()
{
if (somecondition)
{
do something
}
else
{
do something completely different
}
}
GPU artık her iş parçacığında aynı şeyi yapmadığı için GPU'da daha yavaş çalışma eğilimindedir.
Bu basitleştirilmiş bir açıklamadır çünkü dikkate alınması gereken birçok faktör vardır. Örneğin, CPU ve GPU arasında veri göndermek de zaman alıcıdır. Bazen ekstra gönderme süresinden kaçınmak için, CPU'da daha hızlı olduğunda bile GPU'da bir hesaplama yapmaya değer (ve tersi).
Ayrıca birçok modern CPU, hiper iş parçacıklı çok çekirdekli işlemcilerle eşzamanlılığı da destekliyor.
GPU'lar da özyineleme için o kadar iyi görünmüyor, muhtemelen QR algoritmasıyla ilgili bazı sorunları açıklayan buraya bakın . Kişinin bazı özyinelemeli veri bağımlılıkları olduğuna inanıyorum.