openclAan de slag met opencl


Opmerkingen

Deze sectie geeft een overzicht van wat opencl is en waarom een ontwikkelaar het misschien wil gebruiken.

Het moet ook alle grote onderwerpen in opencl vermelden en een link naar de gerelateerde onderwerpen bevatten. Aangezien de documentatie voor opencl nieuw is, moet u mogelijk eerste versies van die gerelateerde onderwerpen maken.


Opencl is een api die gpus, cpus en sommige andere versnellers (zoals een pcie-fpga) in goed gebruik van C99-achtige berekeningen plaatst, maar met een zeer breed concurrency-voordeel. Nadat de installatie en de basisimplementatie zijn voltooid, past alleen eenvoudige wijzigingen in een kerneltekenreeks (of het bijbehorende bestand) automatisch een algoritme toe op N-hardware threads.

Een ontwikkelaar wil het misschien gebruiken omdat het veel gemakkelijker te optimaliseren is voor geheugenruimte of snelheid dan hetzelfde te doen op opengl of direct-x. Het is ook royaltyvrij. Gelijktijdigheid binnen een apparaat is impliciet, dus geen expliciete multi-threading voor elk apparaat. Maar voor configuraties met meerdere apparaten is nog steeds een cpu-multi-threading nodig. Wanneer bijvoorbeeld een taak met 1000 threads naar een cpu wordt verzonden, wordt threadsynchronisatie door het stuurprogramma afgehandeld. Je vertelt hem gewoon hoe groot een werkgroep moet zijn (zoals 256 elk verbonden met virtueel lokaal geheugen) en waar synchronisatiepunten zijn (alleen wanneer nodig).

Het gebruik van gpu voor algemene doeleinden is bijna altijd sneller dan cpu. U kunt dingen sneller sorteren, matrices 10x sneller vermenigvuldigen en in "geen" tijd links in het geheugen blijven staan. Elke 200 $ desktop-grade gpu zal sneller eindigen in een fysieke (eindige-element-methode vloeistof) werklast dan elke 200 $ cpu. Opencl maakt het eenvoudiger en draagbaar. Als je klaar bent met werken in C #, kun je gemakkelijk naar java-opencl implementatie gaan met dezelfde kernels en C ++ project (natuurlijk met behulp van JNI met extra C ++ compilatie).

Voor het grafische gedeelte hoeft u niet altijd buffers te verzenden tussen cpu en gpu. U kunt puur op gpu werken met de "interop" -optie in het onderdeel voor het maken van een context. Met Interop kunt u geometrieën voorbereiden met de limietprestaties van GPU. Geen pci-e vereist voor hoekpuntgegevens. Er wordt alleen een "opdracht" doorgestuurd en er wordt alleen gewerkt aan de binnenkant van de grafische kaart. Dit betekent geen cpu-overhead voor gegevens. Opencl bereidt geometriegegevens in, opengl geeft deze weer. CPU wordt vrijgegeven. Als bijvoorbeeld een enkele thread van cpu een 32x32 vertakte bol kan bouwen in 10000 cycli, dan kan een gpu met opencl 20 bollen bouwen in 1000 cycli.


C # implementatie van OpenCL 1.2: aantal platforms voor een AMD-systeem in 64-bits vensters

OpenCL is API van laag niveau, dus het moet eerst in "C-ruimte" worden geïmplementeerd. Daarvoor moet je header-bestanden downloaden van de site van Khronos. Mijn hardware is AMD en kan versie 1.2 downloaden

opencl.h 
cl_platform.h 
cl.h 
cl_ext.h 
cl_egl.h 
cl_dx9_media_sharing.h 
cl_d3d10.h 
cl_d3d11.h 
cl_gl.h 
cl_gl_ext.h 
cl.hpp
 

vanaf deze pagina

zou voldoende moeten zijn voor C ++ bindingen, dus na het toevoegen van deze bestanden aan uw project en het instellen van de juiste binaire (en bibliotheek) bestandslocaties (

$ (AMDAPPSDKROOT) \ lib \ x86_64 voor 64-bit amd-bibliotheek (bibliotheken van amd app sdk hebben de voorkeur)

,

C: \ Windows \ SysWOW64 voor 64-bit opencl.dll (.so-bestand als ICD een Linux-systeem is)

bijvoorbeeld, maar anders voor Intel-Nvidia), kunt u beginnen met het opvragen van een lijst met platforms (amd, intel, xilinx, nvidia) na het installeren van de juiste stuurprogramma's (zoals crimson voor amd). Stuurprogramma's zijn bedoeld voor het uitvoeren van de opencl-toepassing (met ICD), bibliotheken en header-bestanden moeten kort worden ontwikkeld.

Platforms opvragen:

#define __CL_ENABLE_EXCEPTIONS
#include "stdafx.h"
#include <vector>
#include <CL/cl.hpp>

extern "C"
    {
       // when this class is created, it contains a list of platforms in "platforms" field.
       class OpenClPlatformList
       {
           public:
               std::vector<cl::Platform> platforms;
               int platformNum;
               OpenClPlatformList()
               {
                   platforms= std::vector< cl::Platform>();
                   cl::Platform::get(&platforms);
                   platformNum= platforms.size();
               }
        };


        // this is seen from C# when imported. Creates an object in memory.
        __declspec(dllexport)
            OpenClPlatformList * createPlatformList()
        {
            return new OpenClPlatformList();
        }

        __declspec(dllexport)
            int platformNumber(OpenClPlatformList * hList)
        {
            return hList->platformNum;
        }


        __declspec(dllexport)
            void deletePlatformList(OpenClPlatformList * p)
        {
            if (p != NULL)
                delete p;
            p = NULL;
        }


    }
 

kan worden ingebouwd in een dll (zoals OCLImplementation.dll)

en om het van C # kant te gebruiken,

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;


namespace WrapperCSharp
{
    public class WrapperCSharp
    {
        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern IntPtr createPlatformList();

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern int platformNumber(IntPtr hList);

        [DllImport("OCLImplementation", CallingConvention = CallingConvention.Cdecl)]
        private static extern void deletePlatformList(IntPtr hList);
    }
}
 

natuurlijk moet de dll worden gezien door het C # -project, simpelweg door het in de buurt van het uitvoerbare project te zetten lost het op.

Als de voorbeeldcomputer nu ten minste één opencl-geschikt platform heeft,

IntPtr platformList = createPlatformList(); // just an address in C-space
int totalPlatforms = platformNumber(platformList); // AMD+NVIDIA systems should have "2"
deletePlatformList(platformList); //
 

De variabele totalPlatforms moet ten minste "1" hebben. Vervolgens kunt u variabele platforms in C-ruimte gebruiken met behulp van extra functies om alle platforms te doorlopen om alle apparaten zoals CPU, GPU en speciale versnellers zoals phi of sommige FPGA te doorzoeken.

Je schrijft niet alleen al deze C ++ naar C # wrappers voor tijdkritische projecten. Er zijn veel wrappers geschreven voor C #, Java en andere talen. Voor Java is er "Aparapi", dat is de "Java bytecode naar OpenCl-C" converter API die wat je schrijft puur in Java naar een gpu-parallelle versie op de vlieg, zodat het enigszins draagbaar is.

OpenCL en C #

Voor C # bestaan er veel wrappers die een interface bieden om te communiceren met OpenCL.

  • OpenCL.NET: dit is een van de meest low-level wrappers die er zijn. Het biedt een volledige implementatie van de OpenCL API voor C # zonder enige abstractie toe te voegen. Dus C \ C ++ voorbeelden zijn gemakkelijk geport voor deze bibliotheek. De enige projectpagina is momenteel op codeplex, die wordt afgesloten op 15.12.2017 maar het pakket is beschikbaar op NuGet

https://openclnet.codeplex.com/

  • NOpenCL: Deze bibliotheek biedt een abstracte interface tussen C # en OpenCL.

Het doel op korte termijn is het bieden van een eenvoudig te gebruiken abstracte laag die toegang biedt tot de volledige mogelijkheden van OpenCL zonder in te boeten op prestaties.

https://github.com/tunnelvisionlabs/NOpenCL

  • Cloo:

Cloo is een open source, eenvoudig te gebruiken, beheerde bibliotheek waarmee .NET / Mono-applicaties volledig kunnen profiteren van het OpenCL-framework.

https://sourceforge.net/projects/cloo/

voorwaarden

Als je een moderne CPU of grafische kaart (GPU) in je machine hebt, is de kans groot dat je alles klaar hebt voor de eerste stappen in OpenCL. Om erachter te komen of uw processor OpenCL ondersteunt, kan dit meestal via de startpagina van de fabrikant worden gedaan. Een goede eerste start is de officiële documentatie op

https://www.khronos.org/conformance/adopters/conformant-products#opencl

Wat is OpenCL?

Open Computing Language (OpenCL) is een framework voor het schrijven van programma's die worden uitgevoerd op CPU's, GPU's en andere parallelle processors en versnellers.

OpenCL specificeert een programmeertaal (gebaseerd op C) die toegang biedt tot genoemd on-chip geheugen, een model voor het parallel uitvoeren van taken en de mogelijkheid om die taken te synchroniseren.

Wat is OpenCL?

OpenCL staat voor Open C omputing L aal. OpenCL is een Framework voor parallelle programmering op heterogene platforms, genaamd compute-apparaten , variërend van CPU's over GPU's tot meer speciale platforms zoals FPGA's. OpenCL biedt een standaardinterface voor parallel computergebruik op deze compute-apparaten, maar ook parallelliteit tussen apparaten. Het specificeert een programmeertaal, gebaseerd op C99, en minimumvereisten van basisfuncties geïmplementeerd op apparaten die OpenCL ondersteunen. OpenCL beschrijft verder een abstract reken- en geheugenmodel, dat zo algemeen mogelijk is om het hergebruik van code tussen verschillende platforms eenvoudig te maken.