Sök…


Introduktion

Detta ämne belyser olika sätt att placera data någonstans där din enhet kan komma åt dem.

Läser en matris

För att läsa en matris från enheten tillbaka till värden ringer man

clEnqueueReadBuffer($queue, $memobj, $blocking, $offset, $size, $target, 0, null, null);

Kön $ är CommandQueue som användes för att fördela minnet på enheten. $ Memobj innehåller adressen till enhetsminnet, $ offset och $ storlek definierar ytterligare var och hur mycket data som ska kopieras. Målet $ är en pekare till värdminnet där data lagras i. Målet för $ måste allokeras och ha en lämplig storlek.

Läsa en struktur

Att läsa en bild är nästan som att läsa en matris. Den enda skillnaden att storlek och offset behöver vara tredimensionell.

clEnqueueReadImage($queue, $memobj, $blocking, $offset, $size, $stride, $slice_pitch, $target, 0, null, null);

$ Steg definierar hur många byte en rad har. Normalt är detta bara bredd * (byte per pixel), men någon kanske vill ändra det för att anpassa data till minnesbankerna. Detsamma gäller för $ slice_pitch, bara att detta värde är för den tredje dimensionen.

Att skriva en 2D-struktur

För att kopiera en struktur till enheten finns det två steg som krävs

  1. Tilldela minnet på enheten
  2. Kopiera bilden till enheten
  _mem = clCreateImage2D($context, $mem_flags, $image_format, $width, $height, $stride, $source, &err);

$ Mem_flags definierar hur minnet allokeras. Det kan antingen bara läsas, endast skrivas eller båda. Dessutom kan du definiera var och hur minnet ska allokeras. $ bredd, $ höjd och $ steg är ganska självförklarande.

Om dina mem_flags kopierar data är du klar. Om du vill göra det manuellt vid en senare tidpunkt måste du ringa en annan funktion när du är redo.

err = clEnqueueWriteImage($queue, _mem, $blocking, $offset, $size, $stride, $slice_pitch, $source, 0, null, null);

$ Offset och $ storlek definierar bildområdet som du vill kopiera till målminnet. $ Steg definierar hur många byte en rad har. Normalt är detta bara bredd * (byte per pixel), men någon kanske vill ändra det för att anpassa data till minnesbankerna. Detsamma gäller för $ slice_pitch, bara att detta värde är för den tredje dimensionen. Både $ steg och $ slice_pitch måste matcha dina inmatningsdata.

Minnesflaggor

När du tilldelar minne kan du välja mellan olika lägen:

  • Läs endast minne
  • Skriv bara minne
  • Läs / skriv minne

Läsminnet tilldelas i __konstantminnesregionen, medan de andra två är allokerade i det normala __globalområdet.

Förutom tillgängligheten kan du definiera var minnet är allokerat.

  • Ej specificerat: Ditt minne tilldelas enhetens minne som du kan förvänta dig. Källpekaren $ kan ställas in på null.
  • CL_MEM_USE_HOST_PTR: Detta berättar för enheten att data finns i system RAM och inte bör flyttas. Istället manipuleras data direkt i ram.
  • CL_MEM_COPY_HOST_PTR: Ber enheten att kopiera alla värden på den angivna adressen till enhetsminnet eller, med CL_MEM_ALLOC_HOST_PTR, till ett separat minnesområde i systemramen.
  • CL_MEM_ALLOC_HOST_PTR: Berättar för enheten att tilldela utrymme vid systemramen. Om den används som den enda parametern kan $ källpekaren ställas in på noll.

Snabbmässigt är åtkomst till enhetens globala minne det snabbaste. Men du måste också ringa det två gånger för att kopiera data. Att använda värdpekaren är den långsammaste, medan Alloc_host_ptr erbjuder högre hastighet.

När du använder use_host_ptr, gör enheten exakt det: Den använder dina data i systemramen, som naturligtvis sökas av OS. Så varje minnessamtal måste gå igenom cpu för att hantera potentiella sidfunktioner. När data finns tillgängliga kopierar cpu-enheten till det fästade minnet och skickar det till DMA-styrenheten med värdefulla CPU-klockcykler. Tvärtom allokerar alloc_host_ptr fästat minne i systemramen. Detta minne är placerat utanför sidväxlingsmekanismen och har därför en garanterad tillgänglighet. Därför kan enheten hoppa över cpu helt vid åtkomst till systemram och använda DMA för att snabbt kopiera data till enheten.

Skriva en matris

Att skriva en matris består av två steg:

  1. Tilldela minnet
  2. Kopiera data

För att tilldela minnet, ett enkelt samtal till

_mem = clCreateBuffer($queue, $mem_flags, $size, $host_ptr, &err);

är tillräckligt. Om du bestämde dig för att kopiera värdpekaren via mem_flags är du klar. Annars kan du kopiera data när du vill med

err = clEnqueueWriteBuffer($queue, _mem, $blocking, $offset, $size, $source, 0, null, null);


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow