#include #include "CL/cl.hpp" #include void compareResults (double CPUtime, double GPUtime, int trial) { double time_ratio = (CPUtime / GPUtime); std::cout << "VERSION " << trial << " -----------" << std::endl; std::cout << "CPU time: " << CPUtime << std::endl; std::cout << "GPU time: " << GPUtime << std::endl; std::cout << "GPU is "; if (time_ratio > 1) std::cout << time_ratio << " times faster!" << std::endl; else std::cout << (1/time_ratio) << " times slower :(" << std::endl; } double timeAddVectorsCPU(int n, int k) { // adds two vectors of size n, k times, returns total duration std::clock_t start; double duration; int A[n], B[n], C[n]; for (int i=0; i all_platforms; cl::Platform::get(&all_platforms); if (all_platforms.size()==0) { std::cout<<" No platforms found. Check OpenCL installation!\n"; exit(1); } cl::Platform default_platform=all_platforms[0]; // std::cout << "Using platform: "<()<<"\n"; // get default device (CPUs, GPUs) of the default platform std::vector all_devices; default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices); if(all_devices.size()==0){ std::cout<<" No devices found. Check OpenCL installation!\n"; exit(1); } // use device[1] because that's a GPU; device[0] is the CPU cl::Device default_device=all_devices[1]; // std::cout<< "Using device: "<()<<"\n"; cl::Context context({default_device}); cl::Program::Sources sources; std::cout << CL_DEVICE_MAX_WORK_ITEM_SIZES << std::endl; exit(1); // calculates for each element; C = A + B std::string kernel_code= // is equivalent to the host's "time_add_vectors" function, except the // timing will be done on the host. " void kernel looped_add(global const int* v1, global const int* v2, global int* v3, " " global const int* constants) {" " int ID, Nthreads, n, k, ratio, start, stop;" " ID = get_global_id(0);" " Nthreads = get_global_size(0);" " n = constants[0];" // size of vectors " k = constants[1];" // number of loop iterations "" " ratio = (n / Nthreads);" // elements per thread " start = ratio * ID;" " stop = ratio * (ID+1);" "" " int i, j;" // will the compiler optimize this anyway? probably. " for (i=0; i(default_device) << std::endl; exit(1); } int n, k, Nthreads; n = 128000; // size of vectors k = 1000; // number of loop iterations Nthreads = 128; int constants[2] = {n, k}; // run the CPU code float CPUtime = timeAddVectorsCPU(n, k); // run some GPU code; this block allocates space, writes buffers, and then // adds the same two vectors multiple times -- i.e. it's equivalent to the // host (CPU) code above, but with some necessary overhead. cl::CommandQueue queue(context, default_device); cl::KernelFunctor add(cl::Kernel(program, "add"), queue, cl::NullRange, cl::NDRange(Nthreads), cl::NullRange); cl::Kernel looped_add = cl::Kernel(program, "looped_add"); cl::Kernel add_single = cl::Kernel(program, "add_single"); // construct vectors int A[n], B[n], C[n]; for (int i=0; i