Задача:OpenCL, сумма векторных элементов целочисленных
В OpenCL 1.2, там нет встроенной функции, как
long sum_int4_elements_into_long(int4 v);
Что я пробовал:
Так Я использую код ниже (предварительно загруженная внутренняя часть развернутого цикла)
// acc is long
int4 tmp=arr[i+7];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+6];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+5];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+4];"
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+3];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+2];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i+1];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
tmp=arr[i];
acc+=tmp.x+tmp.y+tmp.z+tmp.w;
суммировать (уменьшить) все элементы целочисленного массива (int4 arr) в одну длинную переменную с ускорением только от +% 20 до +% 30 по сравнению с серийным кодом. Если бы он мог включить SSE или AVX, это было бы намного быстрее.
также попыталось:
с использованием чистого целочисленного аккумулятора ускоряет операцию суммирования вверх 3x, но целочисленные переполнения, так что я могу использовать только длинную переменный. Тогда я попытался с помощью long4 и long2 переменных как
// acc is a long4, arr is an int4 array
acc+=convert_long4(arr[...])
// acc is a long2, arr is an int2 array
acc+=convert_long2(arr[...])
, но это не удалось, и запер компьютер (проверена индексация и ограничение, нет никаких проблем), так что должна быть проблема с longn в INTN при отображениях команд аппаратного обеспечения с процессором AMD.
Разъяснение:
Там должен быть какой-то эквивалент SIMD (SSE или AVX) Инструкция по сборке AMD и INTEL для
32 bit integers in a 128-bit SSE register
| | | |
acc+=tmp.x + tmp.y + tmp.z + tmp.w
^
|
64-bit register
но почему-то OpenCL оленья кожа есть отображение этого или я не укладывалось C99 достаточно хорошо, поэтому cl-компилятор не может использовать инструкции SSE/AVX.
Ближайшие встроенный поплавковые версии
acc=dot(v,(float4)(1,1,1,1));
, но мне нужна целочисленная версия этого, потому что FP нуждается Суммирование коррекции Кагана, который нуждается в дополнительное время.
Edit:
Я не уверен, если ИНТ ИНТ ИНТ ИНТ будет иметь надлежащий длинный результат или просто иметь переполнения Int в длинный.
OpenCL версии: 1.2 работает на CPU (Java ----> Jocl)
CPU: AMD FX-8150
ОС: 64-разрядная версия Windows 10
Driver: последние один на драм ,
Дата: 23.09.2015
Для сравнения:
16М 32-битных чисел, FX8150 @ 3300MHz (с использованием 6 ядер из 8)
серийный код на Java 1.8_25 занимает 16,5 мс в среднем.
IntStream из Java-1.8 занимает 13,5 мс в среднем (X.reduce (0, Integer :: сумма))
Параллельный код в этом вопросе занимает 12,5 мс в среднем (с использованием одного рабочую группу)
Параллельный код в этом вопросе занимает 5,8 мс в среднем на (с использованием четырех рабочих групп)
Parallel но перелива недлинного версия принимает 5мс. (Ударяя ПСП)
МФА Ответ:
acc=dot(v,(double4)(1,1,1,1));
занимает 13,5 мс в среднем, но всплывают версия занимает 12,2 мс в среднем.
Я не уверен, что поплавок может всегда сохранять свою точность, чтобы добавить 1.0 (или даже 0.0) к очень большому числу fp.
http://stackoverflow.com/questions/10811413/sum-vector-components-in-opencl-sse-like –