Performance with CUDA against CPU

username: lfsalasg
cooked: <p>Hi, I’m trying to understand the CUDA implementation and how to increase performance of the neural network but I’m facing the following issue and I will like any guidance on the topic. I’m performing a very simplistic forward pass for a random tensor (code attached). However, I’m getting better timing using the CPU when compared with the GPU (a result I didn’t expected)</p>
<pre><code class="lang-auto">import random
from time import time

import torch

class SmallModel(torch.nn.Module):
    def __init__(self, in_f) -&gt; None:
        super().__init__()
        self.cnn = torch.nn.Sequential(
            torch.nn.Linear(in_f, 200),
            torch.nn.ReLU(),
            torch.nn.Linear(200,200),
            torch.nn.ReLU(),
            torch.nn.Linear(200,200),
            torch.nn.ReLU(),
            torch.nn.Linear(200,100)
        )
    
    def forward(self, x:torch.Tensor)-&gt;torch.Tensor:
        print(x.device)
        return self.cnn(x)

device = 'cuda'

a = torch.randn((100,100))
a = a.to(device)
m = SmallModel(100, device)
m = m.to(device)
start_time = time()
b = m(a)

print(f"Total time: {(time() - start_time)*1000} ms with device {device}")
</code></pre>
<p>The timing for this evaluation is:<br>
with CUDA: 398 ms<br>
with CPU: 1.50 ms</p>
<p>The specifications of my computer are:<br>
GPU: Nvidia Geforce 1660 TI 6GB with CUDA 11.7<br>
CPU: AMD Ryzen 7 2700X 8 core<br>
Memory: 24 GB<br>
Pytorch version: 1.13.0+cu117</p>
<p>I will sincerely appreciate any hint on this topic.</p>

username: artyom-beilis
cooked: <p>Several points:</p>
<ol>
<li>
<p>You need to do at least some warmup - because 1st execution is never optimal neither on CPU nor GPU:</p>
<p>So add stuff like:</p>
<pre><code class="lang-auto">for k in range(20):
    b=m(a)
</code></pre>
<p>Before you take measurement</p>
</li>
<li>
<p>The network is really tiny to have significant benefit for GPU.</p>
</li>
<li>
<p>Measure over several iterations of execution to get reliable values</p>
</li>
<li>
<p>Since pytorch GPU execution is asynchronous - make sure at the end you have synchronisation point (like taking some result to CPU) <code>b[0,0].item()</code></p>
</li>
</ol>

username: lfsalasg
cooked: <p>Hi, thanks for the hints and sorry about the delayed reply. I did change some parameter and found that doing around 100 loops or so does show a slightly better performance of the GPU.</p>
<p>Since I was doing this tests in order to understand the best way for deploying a ANN for some real time applications, I will like to know what is the best way to implement it without the large overhead of transfering the data to the GPU. I will really appreciate any suggestion or literature about this topic.</p>
<p>Thanks!</p>

username: artyom-beilis
cooked: <p>It all depends on network size, for some tiny networks it is indeed does not make huge difference, however take in account that usually the data is relatively small, you keep the network in GPU and only transfer in inputs and outputs to CPU.</p>
<p>Once again your network is really tiny that does not utilize the power of GPU. So it depends on the specific setup. If you start with conv-nets or something bigger GPU is much more powerful.</p>