Warum ist die GPU langsamer als die CPU bei der Durchführung von SVD in einem doppelten Präzisionsarray?Python

Python-Programme
Guest
 Warum ist die GPU langsamer als die CPU bei der Durchführung von SVD in einem doppelten Präzisionsarray?

Post by Guest »

Ich bekomme sowohl in Julia als auch in Python die gleichen Ergebnisse. Die Zersetzung von Singularwert ist bei der GPU langsamer als bei der CPU für Float64 -Arrays. (Float32-Arrays verhalten sich, wie man erwarten würde, wobei die GPU schneller ist.) < /P>
Python-Benchmark-Code mit PyTorch: < /p>

Code: Select all

import time
import torch
from torch.linalg import svd

f64 = torch.double
f32 = torch.float

cpu = torch.device("cpu")
gpu = torch.device("cuda")

# X = torch.rand(5_000, 10_000, dtype=f32)
X = torch.rand(5_000, 10_000, dtype=f64)

X_cpu = X.to(cpu)
X_gpu = X.to(gpu)

print(X_cpu.type())
# Warmup
U, Sig, Vt = svd(X_cpu, full_matrices = True)
# Timed run (CPU)
t1 = time.perf_counter()
U, Sig, Vt = svd(X_cpu, full_matrices = True)
t2 = time.perf_counter()
print(U.type())

print(X_cpu.type())
# Warmup
U, Sig, Vt = svd(X_gpu, full_matrices = True)
# Timed run (GPU)
t3 = time.perf_counter()
U, Sig, Vt = svd(X_gpu, full_matrices = True)
t4 = time.perf_counter()
print(U.type())

print(f"Time CPU (s): {t2-t1}")
print(f"Time GPU (s): {t4-t3}")
< /code>
Für das obige Float64-Array bekomme ich: < /p>
Time CPU (s): 14.52491476599971
Time GPU (s): 56.79755901500175
< /code>
Wenn ich ein Float32-Array verwende, erhalte ich das viel vernünftigere Aussehen: < /p>
Time CPU (s): 9.301500292000128
Time GPU (s): 6.969021153003268
< /code>
Obwohl es immer noch ein wenig überraschend ist, dass die Verwendung der GPU die Dinge nur um ein paar Sekunden beschleunigt. /p>
using LinearAlgebra
using Flux
using CUDA
using cuDNN

X = rand(5_000, 10_000)
println("typeof(X): $(typeof(X))")
# Warmup
U, Sig, V = LinearAlgebra.svd(X)
# Timed run
t1 = time_ns()
U, Sig, V = LinearAlgebra.svd(X)
t2 = time_ns()

println("typeof(U): $(typeof(U))")

X_gpu = X |> gpu |> f64
println("typeof(X_gpu): $(typeof(X_gpu))")

# Warmup
U, Sig, V = CUDA.svd!(X_gpu)
# Timed run
t3 = time_ns()
U, Sig, V = CUDA.svd!(X_gpu)
t4 = time_ns()
println("typeof(U): $(typeof(U))")

println("Time CPU (s): $((t2-t1)/1e9)")
println("Time GPU (s): $((t4-t3)/1e9)")
< /code>
Für dieses Float64-Array dauert die GPU erneut viel länger als die CPU: < /p>
Time CPU (s): 28.641290506
Time GPU (s): 57.069009417
< /code>
Die Umstellung auf Float32 ergibt jedoch erneut ein vernünftiges Ergebnis: < /p>
Time CPU (s): 15.096364932
Time GPU (s): 7.283513658
< /code>
Zwei Fragen: < /p>
[list]
[*] Warum laufen Float64 -Arrays so schlecht auf der GPU? Ich verwende eine GPU der NVIDIA 40 -Serie, wenn dies relevant ist. (Besonders für Float64 -Arrays, aber auch für Float32 -Arrays zu beschleunigen.) Ein möglicher Weg wäre, indem sie die Art und Weise ändern, wie SVD durchgeführt wird. Ich habe überprüft und es scheint keine optionalen Argumente für die SVD -Funktion von CUDA.JL zu geben. Ich habe versucht, full_matrices = false 
für die SVD -Funktion von Pytorch festzulegen, aber ich habe die gleichen Ergebnisse erhalten.
[/list]

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post