Ein 1D-Datensatz ist in Segmente unterteilt, jedes Arbeitselement verarbeitet ein Segment. Es liest eine Reihe von Elemente aus dem Segment? Die Anzahl der Elemente ist vorher nicht bekannt und unterscheidet sich für jedes Segment.Berechnen von Partialsummen in OpenCL
Zum Beispiel:
+----+----+----+----+----+----+----+----+----+ <-- segments
A BCD E FG HIJK L M N <-- elements in this segment
Nachdem alle Segmente Prozesse gewesen sein sollten sie die elements
in aneinander angrenzend Ausgabespeicher schreiben, wie
A B C D E F G H I J K L M N
So ist die absolute Ausgangsposition der Elemente von einem Segment hängt von der Anzahl der Elemente in den vorherigen Segmenten ab. E
befindet sich an Position 4, da Segment 1 Element (A) und Segment 2 3 Elemente enthält.
Der OpenCL-Kernel schreibt die Anzahl der Elemente für jedes Segment in einen lokalen/Shared-Memory-Puffer und funktioniert wie folgt (Pseudo-Code)
kernel void k(
constant uchar* input,
global int* output,
local int* segment_element_counts
) {
int segment = get_local_id(0);
int count = count_elements(&input[segment * segment_size]);
segment_element_counts[segment] = count;
barrier(CLK_LOCAL_MEM_FENCE);
ptrdiff_t position = 0;
for(int previous_segment = 0; previous_segment < segment; ++previous_segment)
position += segment_element_counts[previous_segment];
global int* output_ptr = &output[position];
read_elements(&input[segment * segment_size], output_ptr);
}
So wird jede Arbeitseinheit hat eine Teilsumme zu berechnen Verwenden einer Schleife, bei der die Arbeitselemente mit der größeren ID weitere Iterationen ausführen.
Gibt es eine effizientere Möglichkeit, dies zu implementieren (jedes Arbeitselement berechnet eine Teilsumme einer Sequenz bis zu seinem Index) in OpenCL 1.2? OpenCL 2 scheint dafür work_group_scan_inclusive_add
bereitzustellen.