4
$\begingroup$

I am using an existing GCC C++ x86 Qt application that filters, displays and stores results computed by some C code. Since the computation by now got too complex for CPUs I intend to port the small C program to some GPU computing platform. So the C code should execute tasks received from the x86 GUI, running them parallelized on the GPU and send back the results for final processing.

Unfortunately I am totally new to GPU computing. I read a lot about different hardware, drivers, languages, libraries, compilers, versions etc. and I am a bit confused. I hope someone can help me to choose the right paths.

These are my requirements (most important first):

  • Everything should run and build on Linux (Ubuntu)
  • Since it is a hobby project, all software should be free of charge
  • GPU code should be written in C (C++ would be a bonus)
  • GPU code should be executable on a Tesla T4 card
  • GPU code should be executable on a x86 CPU without major code changes (the development system does not have a GPU card)
  • The techniques should be easy to understand by an average software engineer
  • Language and compiler should support 64 bit wide unsigned integers since my C code uses them a lot (128 bit and 256 bit would be a bonus)
  • Independence from the GPU manufacturer (i.e. NVIDIA) would nice
  • The computation tasks will probably run months or even years, so
    efficiency would be nice
  • A way to build the GPU code using Qt creator (avoiding two different build chains) would be nice

Can I meet these requirements? Which tools should I choose?

EDIT: If the requirements can't be fulfilled completely, which solution would help me meeting the most important requirements at the top?

$\endgroup$
6
  • 1
    $\begingroup$ That's too many constraints. Nvidea GPUs are generally programmed using CUDA, but if you do that, then you can't execute the code you write on a CPU any more, and it's generally also difficult to make the code work on other vendors' GPUs (though there is HIP and hipify). $\endgroup$ Commented Oct 8, 2019 at 0:23
  • $\begingroup$ "Too complex" is a bad reason to move to GPUs. "Too slow and very simple" is a good reason to port to GPUs. $\endgroup$
    – user14717
    Commented Oct 8, 2019 at 0:44
  • $\begingroup$ @user14717: Sorry, bad english. "Too complex" in the sense of computational/mathematical effort not in the sense of code complexity. The code actually is pretty simple. $\endgroup$ Commented Oct 8, 2019 at 7:31
  • $\begingroup$ @WolfgangBangerth: I ordered the bullets from most important to least important top down. I.e. the vendor independence isn't very important for me. But it would be important to develop with a CPU-only system (by compilation or maybe using some GPU emulation)... can't that be fulfilled? $\endgroup$ Commented Oct 8, 2019 at 7:38
  • 1
    $\begingroup$ The way you word your question suggests that you think the GPU should be used when the CPU is too slow or when the code is "complex" enough. This is not what GPUs are for. Unless your algorithm has massive parallelism you'll have a hard time getting it to work on a GPU. Even in situations where a GPU is a good idea a 3x speedup is about what you can expect versus heavily optimized, parallel CPU code. $\endgroup$
    – Richard
    Commented Oct 8, 2019 at 15:35

3 Answers 3

2
$\begingroup$

It is recommended to think about parallelization first and then discuss the implementation. Think about what the code does, what data dependencies exist, and what operations can be carried out in parallel.

Then there are several C++ frameworks (alpaka, kokkos, or the ArrayFire library mentioned in another answer) that help you to introduce a layer of abstraction. Thereby, you are able to compile the code for CPU and GPU.

Finally, you can benchmark your application and determine whether your assumption was right that GPU is suitable for the job. Unfortunately, not every application is a good fit to GPU architectures and you should not expect magic speedup numbers all the time.

$\endgroup$
5
  • $\begingroup$ Well the code consists of some nested counting loops doing simple math on 64 bit unsigned integers like AND, OR, XOR, LSHIFT, RSHIFT, ADD, SUB and a little conditional branching. I assumed this could be executed properly in a GPU. $\endgroup$ Commented Oct 8, 2019 at 10:35
  • 1
    $\begingroup$ Possibly, we don't know :-) The question is how the unsigned integers are related? Does the outcome of an operation on a certain integer depend on the operation result of a neighbor integer or something like that? $\endgroup$ Commented Oct 8, 2019 at 10:41
  • $\begingroup$ They are independent. $\endgroup$ Commented Oct 8, 2019 at 19:10
  • $\begingroup$ OK, then parallelization is likely to boost things significantly. However, it still depends on the ratio of compute operations to memory loads, on the problem size, etc. But you will find out during benchmarking. As to implementation, I should add that I have no experience with the frameworks above, but at least kokkos and ArrayFire are gaining attention lately). $\endgroup$ Commented Oct 8, 2019 at 19:36
  • $\begingroup$ Yes, both of these libraries are very interesting. Looks like familiar ground. I will need to do some more research comparing them to OpenACC which also seems to provide what I need. However OpenACC looks a bit like black magic which in my experience tends to cause trouble ;-) $\endgroup$ Commented Oct 8, 2019 at 19:59
3
$\begingroup$

OpenCL is runnable on multicore cpu, intel hd graphics and even DSP cards. It was pretty much the standard for cross platform gpu computing until compute shaders were introduced.

There are various libraries that have OpenCL as a backend such as viennaCL or ArrayFire. Some of these libraries can use other backends for gpu computation such as CUDA, which runs faster but is only available on nvidia gpu's.

OpenCL is C like but viennaCL and ArrayFire are C++ and are very nicely wrapped in an OOP interface. OpenCL is usually compiled dynamically in runtime.

I think that answers all of your requirements.

$\endgroup$
2
$\begingroup$

Before you start down this path it's important to determine whether there's enough data parallelism in your current code to make using a GPU worthwhile. I'd encourage you to start by describing your application and algorithms in more detail in the question.

Depending on the application, there may be computational tasks for which library routines are already available that can take advantage of the GPU- this is true for many tasks in signal and image processing, numerical linear algebra, etc. If there's a library that already does the job, you don't want to reinvent the wheel.

Assuming that you can't find a library that already does important parts of the work for you, one option would be to use OpenMP or OpenACC extensions to C to write code that could be compiled to run either on the GPU or on the CPU. At a level much closer to the hardware, you could use OpenCL. NVIDIA's CUDA isn't an option if you want a solution that will run on other GPU's.

$\endgroup$
6
  • $\begingroup$ The job is to compute the CRC error detection performance of CRC polynomials. This is a very unusual task. I am pretty sure there is no library function covering this. And yes, parallelism is ideal here, since the algorithm must be run for 2^(n-1) polynomials independently where n are checksum widths starting from ~24. $\endgroup$ Commented Oct 8, 2019 at 19:07
  • $\begingroup$ When using OpenACC, which compiler should I use to support both NVIDIA and CPU targets? $\endgroup$ Commented Oct 8, 2019 at 19:09
  • $\begingroup$ The PGI compiler supports both NVIDIA and multiprocessor targets for OpenACC. See pgroup.com/resources/accel.htm $\endgroup$ Commented Oct 9, 2019 at 0:05
  • $\begingroup$ One issue here is that in testing each polynomial, rather than running straight-line code, you'll probably have a variety of branching points. That means you don't have data parallelism (doing the same operations on a bunch of data in a vector or matrices) of the sort that GPU's are best at. $\endgroup$ Commented Oct 9, 2019 at 0:07
  • $\begingroup$ Given that you're doing CRC computations, have you considered an FPGA implementation instead of using a GPU? You might get betters answers to your question if you explained your problem in more detail. $\endgroup$ Commented Oct 9, 2019 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.