1) Прагмы - это требование поддержки при компиляции, а не активация самой поддержки (как ты похоже думаешь). То есть cl_khr_fp64 уже задействован, если видяха поддерживает.
2) А если размер массива поменяется при выполнении? Конечно конкретно в этом коде можно и вынести, но погоду это не улучшит.
Сразу сообщаю, что я профилирование делал в AMD CodeXL:
3) Если брать только время вычисления самого kernel, то выигрыш любой распаралеленной задачи на GPU будет при превышении задействования числа ядер CPU. Так что для ускорения достаточно даже 8 задач.
4) Насчет формулы вычисления Local у меня самого много вопросов. Самый большой выигрыш был, когда при work_dim=1 размазывал задачи по всем ядрам видяхи, а это и есть UNITS.
И зачем ты вообще делишь размер буфера, когда надо делить количество его элементов? - что собственно я и сделал.
Mathemat: Короче: что должен делать твой код?
Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования OpenCL даже на распалеленных задачах.
А еще показывает, что CPU в тестере не выбирается.
Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования 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 константа, которая совсем не обязана делить нацело глобальную задачу.
Но сначала тебе надо правильно оценить саму глобальную задачу.
Вот это совершенно не новость. Ну то есть гневно вопить по этому поводу - полная глупость. А вот измерить - совсем другое дело, это может быть практически полезно.
Вот только почему-то этими измерениями мне пришлось заняться... Когда читаешь "есть задержка при передаче" даже не представляешь, насколько она велика.
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). Я еще не разобрался.
Дело в другом. Называй свое 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 уже заюзай наконец - он на все эти вопросы отвечает.
compute units - это количество одновременных выполняемых задач.
max wavefronts/GPU (496) и work-items/GPU (31744) - это очередь на выполнение.
AMD CodeXL уже заюзай наконец - он на все эти вопросы отвечает.
я может чего не понял, пардоны если что. но Вы с Алексеем лично знакомы? Алексей товарисч скромный, на "тыкание" может и не среагировать. но со стороны чего то как то не того..... как то борзо Вы разговариваете, умнее всех? умным быть не грех, кичится этим среди братьев по разуму зазорно однако...
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++.
1) Прагмы - это требование поддержки при компиляции, а не активация самой поддержки (как ты похоже думаешь). То есть cl_khr_fp64 уже задействован, если видяха поддерживает.
2) А если размер массива поменяется при выполнении? Конечно конкретно в этом коде можно и вынести, но погоду это не улучшит.
Сразу сообщаю, что я профилирование делал в AMD CodeXL:
3) Если брать только время вычисления самого kernel, то выигрыш любой распаралеленной задачи на GPU будет при превышении задействования числа ядер CPU. Так что для ускорения достаточно даже 8 задач.
4) Насчет формулы вычисления Local у меня самого много вопросов. Самый большой выигрыш был, когда при work_dim=1 размазывал задачи по всем ядрам видяхи, а это и есть UNITS.
И зачем ты вообще делишь размер буфера, когда надо делить количество его элементов? - что собственно я и сделал.
Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования OpenCL даже на распалеленных задачах.
А еще показывает, что CPU в тестере не выбирается.
Показать, что стадия подготовки к вычислениям происходит не мгновенно и пересылка буфера занимает уйму времени, что и ставит под вопрос целесообразности использования OpenCL даже на распалеленных задачах.
Вот это совершенно не новость. Ну то есть гневно вопить по этому поводу - полная глупость. А вот измерить - совсем другое дело, это может быть практически полезно.
А еще показывает, что CPU в тестере не выбирается.
Возможно это оправдано, но может и перестраховка. В любом случае уверен, что сделано сознательно, чтобы обеспечить эффективность самого процесса тестирования. Точнее оптимизации (поскольку она многопоточна). Тут шансы добиться включения могут появиться, если однозначно и полностью разделить понятие тестирования и оптимизации (на уровне партийной политики), т.е. определить их как разные логические типы использования тестера. С соответствующей (официально различной) программной поддержкой. (Это было бы хорошо во многих отношениях, и я давний сторонник такого разделения/различения. Вплоть до разных кнопок запуска оптимизации и тестирования.)
Тогда теоретически при тестировании можно выбор CPU разрешить, а при оптимизации запретить (это правильно).
Да, с прагмой я перегнул. Если ты будешь работать на своей видяхе и дальше, а код никому не передашь, то no problem. Но если кому-нибудь захочется считать это на карте Barts (скажем, 6870), будут проблемы. Код кернела будет пытаться исполняться, не показывая ошибок.
Не обязательно. Часто намного полезнее увеличивать работу в самом кернеле. Это чтобы нивелировать оверхед, связанный с пересылкой данных.
А твое UNITS - это просто число SIMD engines. Согласно документации,
Число SIMD engines - это строго hardware константа, которая совсем не обязана делить нацело глобальную задачу.
Но сначала тебе надо правильно оценить саму глобальную задачу.
Насчет CPU в тестере - вижу, убедился.
Вот это совершенно не новость. Ну то есть гневно вопить по этому поводу - полная глупость. А вот измерить - совсем другое дело, это может быть практически полезно.
Вот только почему-то этими измерениями мне пришлось заняться... Когда читаешь "есть задержка при передаче" даже не представляешь, насколько она велика.
Mathemat: А твое UNITS - это просто число SIMD engines. Согласно документации,
Число SIMD engines - это строго hardware константа, которая совсем не обязана делить нацело глобальную задачу.
Давай лучше будем использовать официальную документацию:
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.
Дело в другом. Называй свое units хоть бочками, но факт остался фактом: units в твоем коде не делит нацело глобальную задачу (у меня точно не делит: 240/28 - нецелое; у тебя тоже, т.к. у тебя units=18). Это косяк.
И второе: здесь и сейчас ты работаешь с OpenCL для MQL5 (ну так неправильно, но ты меня понял), причем это все же другой OpenCL, чем тот, который от Khronos'a.
P.S. Гиперссылку я не создавал, она сама получилась :)
Почитай в других источниках, что такое "compute units".
Кстати, вот таблица из моей второй статьи. Было бы неплохо, если б ты разобрался во всех этих compute units (18), stream cores (288), processing elements (1440), max wavefronts/GPU (496) и work-items/GPU (31744). Я еще не разобрался.
Дело в другом. Называй свое units хоть бочками, но факт остался фактом: units в твоем коде не делит нацело глобальную задачу (у меня точно не делит: 240/28 - нецелое; у тебя тоже, т.к. у тебя units=18). Это косяк.
Так с чего ты взял за основу количество байт 240? Ты double на байты решил распилить? Ты может и сможешь, а видяха не умеет. Так что 240/8 = 30 doubles.
240 байт - это размер всего буфера из 30 doubles.
И "подобрать целый делитель" - это только рекомендация из официальной документации. И эта рекомендация работает не идеально.
И про UNITS - это не моя отсебятина, а советы с форумов по OpenCL. Я потестил и получил максимальную скорость...
И второе: здесь и сейчас ты работаешь с OpenCL для MQL5 (ну так неправильно, но ты меня понял), причем это все же другой OpenCL, чем тот, который от Khronos'a.
А "другой" - это какой?
Ты путаешь собственные реализации и простые обертки. OpenCL MQL - это только обертка над Khronos OpenCL API. Про отличие OpenCL MQL от Khronos.
compute units - это количество одновременных выполняемых задач.
max wavefronts/GPU (496) и work-items/GPU (31744) - это очередь на выполнение.
AMD CodeXL уже заюзай наконец - он на все эти вопросы отвечает.
compute units - это количество одновременных выполняемых задач.
max wavefronts/GPU (496) и work-items/GPU (31744) - это очередь на выполнение.
AMD CodeXL уже заюзай наконец - он на все эти вопросы отвечает.
я может чего не понял, пардоны если что. но Вы с Алексеем лично знакомы? Алексей товарисч скромный, на "тыкание" может и не среагировать. но со стороны чего то как то не того..... как то борзо Вы разговариваете, умнее всех? умным быть не грех, кичится этим среди братьев по разуму зазорно однако...
Я - чувак простой и отвечаю по делу.
Если действительно хотите понимать OpenCL, а не только предполагать, то придется поставить AMD CodeXL и создать свою обертку на C/C++.
Я могу выложить свою обертку, но в ней есть несколько нелогичных строк из-за недостатка у меня практики на C/C++.
240 байт - это размер всего буфера из 30 doubles.
Ну посмотри сам на свой же код:
А дальше, в последней строке, ты же сам и делишь 240 на 18 (это units для твоей карты).
И "подобрать целый делитель" - это только рекомендация из официальной документации. И эта рекомендация работает не идеально.
Мы работаем с MQL5 OpenCL. Я ориентируюсь на раздел документации на нашем сайте. Конечно, посматриваю и на Khronos.
Ну а у меня максимальная получалась при других параметрах. И чо?
Давай тупо прикинем. 18 задач, выполняемых одновременно на мухах GPU, - это максимум то, что можно сделать на 4-5 нитках CPU. А CPU на x86 эмуляции может организовать гораздо больше ниток. Во всяком случае, если это Intel. Мой бывший Pentium G840 (2 ядра) дал ускорение примерно в 70 раз - на двух unit'ах! Я уже не говорю о том, что вытворяет мой текущий... условно говоря, i7.
Хорошо параллелящаяся задача (посмотри скрипты MetaDriver'a из первой ветки об ocl) позволяет достичь на GPU ускорения до 1000 и больше (в сравнении с исполнением в 1 поток на CPU на MQL5). Если не сможешь найти - могу скинуть, потестишь на своей карте.
ОК, гляну на нее, спасибо.