Why i can't use my full PCI-Express bandwidth?

Hello, Forum!

I know which this question is frequently asked in topics of Developers Forums, but i can’t solve my problem without make my own ask with detailed explanation.

I have make a program which that try to use a full memory of one card of my Titan-Z, the overhead of data transfers means more than 90% of process time. I’m trying offload a buffer of ~32 millions ints to GPU memory, but i can’t reach bandwidth bigger than 3 GB/s on transfer.

It’s very important explain which my code uses cudaMallocHost in a single time to allocate full memory of GPU. When i’ve used Pinned memory i’ve achieved more than ~7 GB/s in data transfer but my computation on GPU turns more expensive after, thus, the final time (computation time + data transfer) is bigger than when i use Pageable memory.

Exists another way to improve bandwith without grow of time computation on GPU? I’ve tried use cuda Streams to parallelize transfer of array chunks but my bandwidth remained the same.

My hardware especifications is following:

Titan-Z:
6 GB (single card used)
GDDR5 364 bit (of single card)
Maximum BW: 336 GB/sec
PCI-Express 3.0 x16 (diagnosed in GPU-Z)

Motherboard bus:
PCI-Express 3.0 x16 (diagnosed in CPU-Z)

My Host Memory:
16 GB DDR3 (2x Dual Channel)
1333 MHz

Thanks for everything!!!

Are you absolutely sure using pinned memory on host side makes computation happening on device more expensive? Doesn’t sound right to me.

Also, if the data transfer accounts for 90% of your program’s time, then what you’re trying to do probably isn’t a good candidate for massive parallelization on GPU.

Pinned memory doubles the bandwidth (approximately) which halves the transfer time (approximately).

However the process of pinning memory using cudaHostAlloc takes much longer than an allocation using malloc.

The net effect on an application which only does a single transfer from/to pinned memory is basically negligible, in terms of execution time. The reduced transfer time is offset by the increased pinning (allocation) time.

Pinned memory will provide a benefit if:

  1. multiple transfers are made to/from the buffer
  2. overlap of copy and compute operations is desired (in which case pinning is mandatory)

remote diagnosis is hard. It is close to impossible to give specific advice in this situation without seeing your code and your benchmarking framework and knowing a bit more about your system.

A number of things look odd here, in particular your statement that the application runs more slowly with pinned memory, and the fact that you achieve at most 7 GB/sec throughput although PCIe is configured for gen3 x16. What are the block sizes of the transfers? You would need blocks of 16 MB or more to achieve full throughput.

Is this a dual socket system by any chance? If so, make sure to use appropriate CPU and memory affinity settings such that the GPU “talks” to the “near” CPU/memory. What CPU is in this system? Are you using simultaneous H2D and D2H transfers? If so, your system memory may not provide sufficient bandwidth, based on your description around 21 GB/sec theoretical peak throughput, not enough to drive full-duplex PCIe gen3 at 12 GB/sec per direction.

If there are multiple PCIe slots on the board, they may not all be created equal. Or, the CPU may not provide enough PCIe lanes to allow all PCIe devices in the machine to operate at the x16 settings, causing demotion to x8 operation. There could also be system BIOS configuration issues.

If you run the application with the profiler, does it clearly show that the GPU and/or transfers to the GPU are the bottleneck? Is it possible there are host-side issues that have not been explored in enough detail?

As njuffa mentioned, maybe the CPU does not have enough PCIe lanes to support 2 GPUs at PCIe 3.0 x16.

There are only a few CPU which have 40 lanes, such as the i7 5930k 3.5 Ghz or the older i7 4820k 3.7 GHz. Newer popular CPU such as the 5820 and the 4790 do not have enough lanes to support 2 GPUs PCIe-3.0 x16.

Which exact CPU and which exact motherboard are you using? How many GPUs total?