trochĘ historii
DESCRIPTION
TROCHĘ HISTORII. PO CO UŻYWAĆ OPENCL?. AMD Radeon HD7870 OC 1,1 GHz. Intel Core i5 2550k OC 4,2 GHz. Intel Core i5 2550k 4 rdzenie. AMD Radeon HD7870 1280 rdzeni. DLACZEGO NIE UŻYWAĆ OPENCL?. CZEGO NAM TRZEBA?. CZAS NA NAJLEPSZE!. KOD!. TRADYCYJNE PODEJŚCIE. - PowerPoint PPT PresentationTRANSCRIPT
Marek Zając
TROCHĘ HISTORII
Marek Zając
Marek Zając
Marek Zając
PO CO UŻYWAĆ OPENCL?
Marek Zając
Intel Core i5 2550k OC
4,2 GHz
AMD Radeon HD7870 OC
1,1 GHz
Marek Zając
Intel Core i5 2550k
4 rdzenie
AMD Radeon HD7870
1280 rdzeni
Marek Zając
Marek Zając
Marek Zając
DLACZEGO NIE UŻYWAĆ OPENCL?
Marek Zając
Marek Zając
CZEGO NAM TRZEBA?
Marek Zając
Marek Zając
Marek Zając
CZAS NA NAJLEPSZE!
Marek Zając
KOD!
Marek Zając
TRADYCYJNE PODEJŚCIE
Marek Zając
double* tab = new double[100000000];
//prepare array...//...
for(int i = 0; i < 100000000; i++){
tab[i] *= 2.5;}
Marek Zając
OPENCL
Marek Zając
double* tab = new double[100000000];
//prepare array...//...
…
Marek Zając
cl_int err;
cl::vector<cl::Platform> platformList;
cl::Platform::get(&platformList);
…
…
Marek Zając
cl_context_properties cprops[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties) (platformList[0])(), 0 };
cl::Context context(CL_DEVICE_TYPE_ALL, cprops, NULL, NULL, &err);
cl::vector<cl::Device> devices;devices = context.getInfo<CL_CONTEXT_DEVICES>();
…
…
Marek Zając
std::ifstream file("func.cl"); std::string prog(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length() + 1));
cl::Program program(context, source);err = program.build(devices, "");
cl::Kernel kernel(program, "func", &err);
…
…
Marek Zając
… JUŻ PRAWIE, JESZCZE TYLKO …
Marek Zając
cl::Buffer in(context, CL_MEM_READ_WRITE, sizeof(double) * 100000000);
cl::CommandQueue queue(context, devices[0], 0, NULL);
const size_t local_ws = 256;
const size_t global_ws = ceil((double)local_ws / 100000000);
cl::Event event;
…
…
Marek Zając
Marek Zając
queue.enqueueWriteBuffer(in, CL_TRUE, 0, sizeof(double) * 100000000, tab);
kernel.setArg(0, in);kernel.setArg(1, 100000000);
queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(global_ws), cl::NDRange(local_ws), NULL, &event);
event.wait();queue.enqueueReadBuffer(in, CL_TRUE, 0, sizeof(double) * 100000000, tab);
…
Marek Zając
CZYŻBY KONIEC?
Marek Zając
Marek Zając
__kernel void func(__global double* in, int n){
size_t id = get_global_id(0);in[id] *= 2.5;
}
Marek Zając
TO MOŻE JAKIŚ TEST?„ŻĄDAMY DOWODÓW!”
Marek Zając
__kernel void func(__global double* in, double x, int n){
size_t id = get_global_id(0);if(id < n){
in[id] *= x;in[id] += 10.0 * x;in[id] = sqrt(in[i]);
}}
Marek Zając
K = 10000000
K * 200
Marek Zając
WYNIK TO…
Marek Zając
CPU
GPU
11,731 sek.
6,068 sek.
Marek Zając
Marek Zając
Marek Zając
double => float
CPU
GPU
12,963 sek.
2,979 sek.
Marek Zając
DZIĘKUJĘ ZA UWAGĘ
ŹRÓDŁA OBRAZKÓW: 99% KRADZIONE Z INTERNETU, 1% WŁAŚNE