OpenCL: реальные задачи - страница 7

 

1) Прагмы - это требование поддержки при компиляции, а не активация самой поддержки (как ты похоже думаешь). То есть cl_khr_fp64 уже задействован, если видяха поддерживает.

2) А если размер массива поменяется при выполнении? Конечно конкретно в этом коде можно и вынести, но погоду это не улучшит.

Сразу сообщаю, что я профилирование делал в AMD CodeXL:

3) Если брать только время вычисления самого kernel, то выигрыш любой распаралеленной задачи на GPU будет при превышении задействования числа ядер CPU. Так что для ускорения достаточно даже 8 задач.

4) Насчет формулы вычисления Local у меня самого много вопросов. Самый большой выигрыш был, когда при work_dim=1 размазывал задачи по всем ядрам видяхи, а это и есть UNITS.

И зачем ты вообще делишь размер буфера, когда надо делить количество его элементов? - что собственно я и сделал.

Mathemat: Короче: что должен делать твой код?

Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования OpenCL даже на распалеленных задачах.

А еще показывает, что CPU в тестере не выбирается.

 
Roffild:

Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования OpenCL даже на распалеленных задачах.

Вот это совершенно не новость.  Ну то есть гневно вопить по этому поводу - полная глупость.  А вот измерить - совсем другое дело, это может быть практически полезно.

А еще показывает, что CPU в тестере не выбирается.

Возможно это оправдано, но может и перестраховка.  В любом случае уверен, что сделано сознательно, чтобы обеспечить эффективность самого процесса тестирования.  Точнее оптимизации (поскольку она многопоточна).  Тут шансы добиться включения могут появиться, если однозначно и полностью разделить понятие тестирования и оптимизации (на уровне партийной политики), т.е. определить их как разные логические типы использования тестера.  С соответствующей (официально различной) программной поддержкой. (Это было бы хорошо во многих отношениях, и я давний сторонник такого разделения/различения.  Вплоть до разных кнопок запуска оптимизации и тестирования.)

Тогда теоретически при тестировании можно выбор CPU разрешить, а при оптимизации запретить (это правильно).

 
Roffild: 1) Прагмы - это требование поддержки при компиляции, а не активация самой поддержки (как ты похоже думаешь). То есть cl_khr_fp64 уже задействован, если видяха поддерживает.

Да, с прагмой я перегнул. Если ты будешь работать на своей видяхе и дальше, а код никому не передашь, то no problem. Но если кому-нибудь захочется считать это на карте Barts (скажем, 6870), будут проблемы. Код кернела будет пытаться исполняться, не показывая ошибок.

4) Насчет формулы вычисления Local у меня самого много вопросов. Самый большой выигрыш был, когда при work_dim=1 размазывал задачи по всем ядрам видяхи, а это и есть UNITS.

Не обязательно. Часто намного полезнее увеличивать работу в самом кернеле. Это чтобы нивелировать оверхед, связанный с пересылкой данных.

А твое UNITS - это просто число SIMD engines. Согласно документации,

local_work_size[] задает подмножество задач, которые будут выполняться указанным кернелом OpenCL программы. Его размерность равна размерности work_items[] и позволяет общее подмножество задач нарезать на более мелкие подмножества без остатков от деления. Фактически, размеры массива local_work_size[] должны быть подобраны таким образом, чтобы глобальное множество  задач work_items[] нарезалось на более мелкие подмножества. В данном примере подойдет local_work_size[3]={10, 10, 10}, так как work_items[40, 100, 320] без остатка можно собрать из массива local_items[10, 10, 10].

Число SIMD engines - это строго hardware константа, которая совсем не обязана делить нацело глобальную задачу.

Но сначала тебе надо правильно оценить саму глобальную задачу.

Насчет CPU в тестере - вижу, убедился.

 
MetaDriver:

Вот это совершенно не новость.  Ну то есть гневно вопить по этому поводу - полная глупость.  А вот измерить - совсем другое дело, это может быть практически полезно.

Вот только почему-то этими измерениями мне пришлось заняться... Когда читаешь "есть задержка при передаче" даже не представляешь, насколько она велика.

Mathemat: А твое UNITS - это просто число SIMD engines. Согласно документации,

Число SIMD engines - это строго hardware константа, которая совсем не обязана делить нацело глобальную задачу. 

Давай лучше будем использовать официальную документацию: 

CL_DEVICE_MAX_COMPUTE_UNITS     cl_uint     The number of parallel compute units on the OpenCL device. A work-group executes on a single compute unit. The minimum value is 1. 
local_work_size
Points to an array of work_dim unsigned values that describe the number of work-items that make up a work-group (also referred to as the size of the work-group) that will execute the kernel specified by kernel.
Так что мои выводы верны и подтверждаются прогоном в AMD CodeXL
 

Дело в другом. Называй свое units хоть бочками, но факт остался фактом: units в твоем коде не делит нацело глобальную задачу (у меня точно не делит: 240/28 - нецелое; у тебя тоже, т.к. у тебя units=18). Это косяк.

И второе: здесь и сейчас ты работаешь с OpenCL для MQL5 (ну так неправильно, но ты меня понял), причем это все же другой OpenCL, чем тот, который от Khronos'a.  

P.S. Гиперссылку я не создавал, она сама получилась :)

Roffild:
CL_DEVICE_MAX_COMPUTE_UNITS     cl_uint     The number of parallel compute units on the OpenCL device. A work-group executes on a single compute unit. The minimum value is 1.

Почитай в других источниках, что такое "compute units".

Кстати, вот таблица из моей второй статьи. Было бы неплохо, если б ты разобрался во всех этих compute units (18), stream cores (288), processing elements (1440), max wavefronts/GPU (496) и work-items/GPU (31744). Я еще не разобрался.


 
Mathemat:

Дело в другом. Называй свое units хоть бочками, но факт остался фактом: units в твоем коде не делит нацело глобальную задачу (у меня точно не делит: 240/28 - нецелое; у тебя тоже, т.к. у тебя units=18). Это косяк.

Так с чего ты взял за основу количество байт 240? Ты double на байты решил распилить? Ты может и сможешь, а видяха не умеет. Так что 240/8 = 30 doubles.

240 байт - это размер всего буфера из 30 doubles.

И "подобрать целый делитель" - это только рекомендация из официальной документации. И эта рекомендация работает не идеально.

И про UNITS - это не моя отсебятина, а советы с форумов по OpenCL. Я потестил и получил максимальную скорость...

Mathemat:

И второе: здесь и сейчас ты работаешь с OpenCL для MQL5 (ну так неправильно, но ты меня понял), причем это все же другой OpenCL, чем тот, который от Khronos'a.

А "другой" - это какой?

Ты путаешь собственные реализации и простые обертки. OpenCL MQL - это только обертка над Khronos OpenCL API. Про отличие OpenCL MQL от Khronos.

 
Mathemat: Кстати, вот таблица из моей второй статьи. Было бы неплохо, если б ты разобрался во всех этих compute units (18), stream cores (288), processing elements (1440), max wavefronts/GPU (496) и work-items/GPU (31744). Я еще не разобрался. 

compute units - это количество одновременных выполняемых задач.

max wavefronts/GPU (496) и work-items/GPU (31744) - это очередь на выполнение.

AMD CodeXL уже заюзай наконец - он на все эти вопросы отвечает.

 
Roffild:

compute units - это количество одновременных выполняемых задач.

max wavefronts/GPU (496) и work-items/GPU (31744) - это очередь на выполнение.

AMD CodeXL уже заюзай наконец - он на все эти вопросы отвечает.

я может чего не понял, пардоны если что. но Вы с Алексеем лично знакомы? Алексей товарисч скромный, на "тыкание" может и не среагировать. но со стороны чего то как то не того..... как то борзо Вы разговариваете, умнее всех? умным быть не грех, кичится этим среди братьев по разуму зазорно однако...

 

Я - чувак простой и отвечаю по делу.

Если действительно хотите понимать OpenCL, а не только предполагать, то придется поставить AMD CodeXL и создать свою обертку на C/C++.

Я могу выложить свою обертку, но в ней есть несколько нелогичных строк из-за недостатка у меня практики на C/C++.

 
Roffild: Так с чего ты взял за основу количество байт 240? Ты double на байты решил распилить? Ты может и сможешь, а видяха не умеет. Так что 240/8 = 30 doubles.

240 байт - это размер всего буфера из 30 doubles.

Ну посмотри сам на свой же код:

uint units = (uint)CLGetInfoInteger(hcontext, CL_DEVICE_MAX_COMPUTE_UNITS);
uint global_work_offset[] = {0};
uint global_work_size[1];
uint local_work_size[1];
global_work_size[0] = ArraySize(price);
Print( "Глобальная задача = ", global_work_size[0] );  /// Это я добавил, вышло 240. Но это и так легко подсчитать: 30*double = 240
local_work_size[0] = global_work_size[0] / units;

А дальше, в последней строке, ты же сам и делишь 240 на 18 (это units для твоей карты).

И "подобрать целый делитель" - это только рекомендация из официальной документации. И эта рекомендация работает не идеально.

Мы работаем с MQL5 OpenCL. Я ориентируюсь на раздел документации на нашем сайте. Конечно, посматриваю и на Khronos.

И про UNITS - это не моя отсебятина, а советы с форумов по OpenCL. Я потестил и получил максимальную скорость...

Ну а у меня максимальная получалась при других параметрах. И чо?

Давай тупо прикинем. 18 задач, выполняемых одновременно на мухах GPU, - это максимум то, что можно сделать на 4-5 нитках CPU. А CPU на x86 эмуляции может организовать гораздо больше ниток. Во всяком случае, если это Intel. Мой бывший Pentium G840 (2 ядра) дал ускорение примерно в 70 раз - на двух unit'ах! Я уже не говорю о том, что вытворяет мой текущий... условно говоря, i7.

Хорошо параллелящаяся задача (посмотри скрипты MetaDriver'a из первой ветки об ocl) позволяет достичь на GPU ускорения до 1000 и больше (в сравнении с исполнением в 1 поток на CPU на MQL5). Если не сможешь найти - могу скинуть, потестишь на своей карте.

Если действительно хотите понимать OpenCL, а не только предполагать, то придется поставить AMD CodeXL и создать свою обертку на C/C++.

ОК, гляну на нее, спасибо.