About nVidia CUDA habrovchane already heard, now it was the turn and AMD Brook +. Brook + allows you to write C programs and run them on AMD video cards (well, as an option, you can automatically generate a CPU version with average code quality). Achievable performance - about 600 billion operations on AMD 4870.
NB : The article is a brief introduction, you should not expect coverage here of all aspects of programming on Brook + :-)
About iron
Brook + works starting with HD2xxx cards (with restrictions), normally starts working from the 3xxx-series. If in advertising you see that there are 4870 800 processors, then in fact there are 160 of them, each of which makes 5 instructions per clock (the 3rd series had serious restrictions on simultaneously executed instructions, the 4th can have almost any). Unlike CUDA, where everything is quite “low-level”, with Brook + the compiler does everything for you, everything is cached everywhere, and stops working quickly at the most inopportune moment. Of the benefits - AMD access memory cards is cached, and nVidia does not.
Where to begin?
As usual, it’s better to start with a working SDK example (I’ll tell on the example of Visual Studio 2005, Linux is also supported). Download the SDK here:
http://ati.amd.com/technology/streamcomputing/sdkdwnld.html. Open samples.sln, you can start with the project hello_brook.
Pay attention to the Custom Build Rule for the hello_brook.br file - it generates .h and .cpp files that you need to use in the project:
mkdir brookgenfiles | "$(BROOKROOT)\sdk\bin\brcc_d.exe" -o "$(ProjectDir)\brookgenfiles\$(InputName)" "$(InputPath)"
Because the preprocessor is not supported, it can be called separately by itself, it may turn out like this:
cl /P /C file.br
copy file.i file_pp.br
"$(BROOKROOT)\sdk\bin\brcc_d.exe" -k -p cal file_pp.br
In the last line -p cal means that only the GPU core is generated, the CPU part will be omitted (it can be compiled for a long time, and is not always needed).
')
Program structure
kernel void your_kernel(float input<>, out float output<>, float val)
{
if (input > val)
{
output = 1.0f;
}
else
{
output = 0.0f;
}
}
Called something like this:
unsigned int dim [] = {800 * 100};
:: brook :: Stream inputStream (1, dim);
:: brook :: Stream outputStream (1, dim);
inputStream.read (_input);
your_kernel (inputStream, outputStream, 123.35);
outputStream.write (_output);
It should be noted that, unlike CUDA, we immediately specify the data for each stream. That's all :-) When working, remember that as long as the arrays and structures in the .br files are not properly supported :-) Also, do not forget to define variables at the beginning of the function body, this is not C ++ :-)
Brook + supports other launch options: when the source data is taken from the common array, when the “coordinates” of the flow (as in CUDA) are determined, which accumulate the cores (that is, you can consider for example the sum of all the numbers in the array). Everyone can read about this in the documentation or in the SDK examples.
Optimization
Optimization methods generally coincide with CUDA:
- As few branches as possible in the code where different threads follow different paths. This code is not executed in parallel.
- Because each processor is superscalar, you need to ensure that you always have at least 5 independent instructions in your code. The easiest way to achieve this is to turn the loop 5 times by hand (I hope in the future this can be done by #pragma unroll (5))
- Use as little memory as possible. The less memory you use, the calmer the cache will be :-)
Does not work?
First of all, you should read the documentation together with the SDK in the Brook + _Documentation folder. Then you can ask at the
official forum - unfortunately there developers are not so often unsubscribe. In Russian, you can ask
me on the forum for example, where I answer :-) Also a lot of people live on
gpgpu.ru .
Conclusion
To summarize: Brook + allows you to achieve phenomenal performance on well-parallel tasks that do not require large amounts of memory, at the cost of additional programming efforts in a not very convenient environment :-).
I hope this introduction will help people figure out how to program Brook +. If there are problems / questions, I will be happy to help. Well, ahead of us is waiting for an introduction to OpenCL and SIMD x86