Render.ru

Нужна помошь знатоков по векторным операциям

Andots

Знаток
Рейтинг
66
#81
А это общая клиника для гпу расчетов, ввод и ввывод данных - потеря скорости.
У амп плюс большой что работать будет и на нвидии и на ати, cuda только на нвидии, опецл по разному и там и там, иногда не совместим.
Да, большой плюс. И он попроще будет чем куда или опен(но потормознее как я понял). Ну Cuda еще куда не шло, там хоть каккто можно мозги на бекрень вывернуть и сделать что то, Опен мне вообще никак пока, не пошел. У меня на борту 780 так что сам бог велел в Cuda лезть, вопрос в том когда есть смысл ее использовать, сейчас немножко подразберусь еще, и попробую практически с замерами посмотреть на что она способна. Ты кстати не в курсе почему у других этот плаг не запускается? Что не так то, вроде и версии одинаковые майки.
 

4i4ikov

Знаток
Рейтинг
37
#82
почему у других этот плаг не запускается? Что не так то, вроде и версии одинаковые майки.
Библиотек наверно нет,
Dependency Walker запустить и посмотреть, только мэмэл-ку кинуть не в плюги а в bin майи

depends.png

там где (?) - этих dll нет
 

Andots

Знаток
Рейтинг
66
#83
Понятно.
Я вчера как то мимо ушей пропустил.
"1 - это на одном ядре, я так понимаю тут никакой векторизации автоматом не делается"
А можешь в двух словах хотя бы на пальцах, какой код должен был бы быть чтоб автоматом векторизация была.
 

4i4ikov

Знаток
Рейтинг
37
#84
Понятно.
Я вчера как то мимо ушей пропустил.
"1 - это на одном ядре, я так понимаю тут никакой векторизации автоматом не делается"
А можешь в двух словах хотя бы на пальцах, какой код должен был бы быть чтоб автоматом векторизация была.
Во первых надо разделять понятия векторизации для циклов и для данных
Для циклов например https://msdn.microsoft.com/ru-ru/library/hh872235.aspx

Для данных берутся типы vector, компилятор лучше взять интеловский, библиотеку поискать интеловскую под векторные вычисления. В итоге sse(или avx) будет работать как действительно sse, одновременно обрабатывая все три компоненты. А в твоем коде sse работает как замена fpu, ну это обычное дело у современных компиляторов, отказ от fpu и перевод математики на simd.

Нашу простенькую функцию можно и на sse асемблере написать, она простая для этого, будет раза в 2-3 быстрее. Но вообще правильно писать всё на сях с типом данных вектор и на интел компилятор бросать.
 

4i4ikov

Знаток
Рейтинг
37
#85

Andots

Знаток
Рейтинг
66
#86
А вот нашёл бложик по sse векторам http://fastcpp.blogspot.ru/
Можно взять его библиотечку http://fastcpp.blogspot.ru/2011/12/simple-vector3-class-with-sse-support.html и просто типом вектор переписать алгоритм.
А интеловский компиллер и их библиотеки ставить если серьезно хоца этим заниматься.

Сматри какая интересная петрушка получилась.

"
-------------------- bench 1000000
C++ Single Thread (Float) External (Python) timer 0.0480000972748
C++ Single Thread (Float) Internal timer 0.047

--------------------
C++ Multi Thread (Float) External (Python) timer 0.0140001773834
C++ Multi Thread (Float) Internal timer 0.013

--------------------
C++ Single Thread (Manual SSE) External (Python) timer 0.0450000762939
C++ Single Thread (Manual SSE) Internal timer 0.044

--------------------
C++ Multi Thread (Manual SSE) External (Python) timer 0.00699996948242
C++ Multi Thread (Manual SSE) Internal timer 0.006

--------------------
C++ Single Thread (Auto SSE) External (Python) timer 0.0869998931885
C++ Single Thread (Auto SSE) Internal timer 0.087

--------------------
C++ Multi Thread (Auto SSE) External (Python) timer 0.0380001068115
C++ Multi Thread (Auto SSE) Internal timer 0.034

--------------------
4i4ikov (scalar): 2.26699995995
Dark (vector): 1.59100008011
"
Теперь поянснения
Ну первая позиция это стандартный вариант

Теперь (Manual SSE), я тут с утра почитал и попробовал векторизовать вручную.
Итог, на 1 ядре скорость особо не выросла, а вот на 4х прирост в 2 раза. Хотя я что то наверно не так сделал по идее прирост даже на 1 ядре должен быть в 3 раза, а уж на 4х.
Код:
    __m128 VecA = _mm_set_ps(Ax, Ay, Az, 1.0f);
    __m128 VecB = _mm_set_ps(Bx, By, Bz, 1.0f);
    __m128 VecC = _mm_set_ps(Cx, Cy, Cz, 1.0f);

for (int i = 1;i < N;++i)

    {
   
        float in = i;
        __m128 Ind = _mm_set_ps(in, in, in, 1.0f);


    __m128 VecA1 = _mm_div_ps(VecA, Ind);
    __m128 VecB1 = _mm_div_ps(VecB, Ind);
    __m128 VecC1 = _mm_div_ps(VecC, Ind);

    __m128 dist = _mm_sub_ps(VecB1, VecA1);
    __m128 dist_st = _mm_mul_ps(dist, dist);
    __m128 C_min_A = _mm_sub_ps(VecC1, VecA1);
    __m128 C_min_A1 = _mm_mul_ps(C_min_A, dist_st);
    __m128 C_min_A2 = _mm_div_ps(C_min_A1, dist_st);
    __m128 ress = _mm_add_ps(VecA, C_min_A2);

    }
А теперь Авто, как по мануалу то по идее цикл должен был векоризоваться.

Код:
    float3 VecAa = { Ax, Ay, Az };
    float3 VecBb = { Bx, By, Bz };
    float3 VecCc = { Cx, Cy, Cz };
        float3 dis;
        float3 summ;
#pragma loop()
        for (int i = 1;i < N;++i)

        {
       
            for (int j = 0; j < 3; ++j)
            {
           
                 dis[j] = VecBb[j] - VecAa[j];


                 summ[j] = VecAa[j] / i + (VecCc[j] / i - VecAa[j] / i)*dis[j] * dis[j] / (dis[j] * dis[j]);
            }
Но по факту скорость упала в 2 раза от исходного варианта.
#pragma loop() и во втором цикле ставил и в обоих, без изменений. /QPar тоже ставил


Попробую сделать как в ссылках что ты дал, посмотрю что получиться.
 
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#87
ты mll покажи релизную, мне код конечный интересней посмотреть

пока на вскидку
__m128 VecA = _mm_set_ps(Ax, Ay, Az, 1.0f);
__m128 VecB = _mm_set_ps(Bx, By, Bz, 1.0f);
__m128 VecC = _mm_set_ps(Cx, Cy, Cz, 1.0f);
Нет выравнивания! Для sse обязательно выравнивать.

И чего-то дохрена делений _mm_div_ps, но сейчас особо не углубляюсь в разбор, поверхностно смотрю, потом может подробней гляну.

А лучше avx возьми, там ограничений меньше.
 

Andots

Знаток
Рейтинг
66
#88
А вот что получилось от буржуя, по ссылке что ты дал

--------------------
C++ Single Thread ( SSE Byrjyi) External (Python) timer 0.542000055313
C++ Single Thread ( SSE Byrjyi) Internal timer 0.539

--------------------
C++ Multi Thread ( SSE Byrjyi) External (Python) timer 0.641000032425
C++ Multi Thread ( SSE Byrjyi) Internal timer 0.638

--------------------

Еще медленней.

Код:
    vector3 VecA1 = { float(Ax),float(Ay),float(Az) };
    vector3 VecB1 = { float(Bx), float(By), float(Bz) };
    vector3 VecC1 = { float(Cx), float(Cy), float(Cz) };

        for (int i = 1;i < N;++i)

        {
            vector3 ind = { float(i),float(i),float(i) };
       
            vector3 dis = VecB1 - VecA1;

            vector3    summ = VecA1 / ind + (VecC1 / ind - VecA1 / ind)*dis * dis / (dis * dis);
            }
 

Andots

Знаток
Рейтинг
66
#89
А, не видел что ты ответил. Лови исходник. Ну а по делениям мог и попариться, уже мозги набекрень

vectors.zip
 

Вложения

4i4ikov

Знаток
Рейтинг
37
#90
Деления можно заменить на умножения
v1/i; v2/i; v3/i
заменить на
d = 1/i; v1*d; v2*d; v3*d
деление 14 тактов, умножение 5-1

Щас гляну чё там скомпилилось...
 

4i4ikov

Знаток
Рейтинг
37
#92
А вот что получилось от буржуя, по ссылке что ты дал
Еще медленней.
Код:
   vector3    summ = VecA1 / ind + (VecC1 / ind - VecA1 / ind)*dis * dis / (dis * dis);
Чекером проверял? результат сходится?
У тебя вместо скалярных произведений стоит обычное умножение
Когда в майе у нас пишется
v1+(v3-v1)*v21*v21/(v21*v21)
на самом деле это
v1+(v3-v1).v21*v21/(v21.v21)
где точка это дот-продакшен, результат - скаляр
а в майе * на две разные операции, поэтому и путаница

У буржуя возьми
// dot product with another vector
inline float dot(const vector3& b) const { return _mm_cvtss_f32(_mm_dp_ps(mmvalue, b.mmvalue, 0x71)); }

и mll покажи
 

Andots

Знаток
Рейтинг
66
#93
Чекером проверял? результат сходится?
У тебя вместо скалярных произведений стоит обычное умножение
Когда в майе у нас пишется
v1+(v3-v1)*v21*v21/(v21*v21)
на самом деле это
v1+(v3-v1).v21*v21/(v21.v21)
где точка это дот-продакшен, результат - скаляр
а в майе * на две разные операции, поэтому и путаница

У буржуя возьми
// dot product with another vector
inline float dot(const vector3& b) const { return _mm_cvtss_f32(_mm_dp_ps(mmvalue, b.mmvalue, 0x71)); }

и mll покажи
Да ,конечно, держи mll. На самом деле суть не в верности или не верности формулы, я насчет этого не заморачиваюсь, хотя незнаю, сильно это влияет на производительность умножение вместо дот продукта?. Просто данный вариант удобен как тестовый стенд для тестирования методов написания кода. Хочу найти самый быстрый метод для дальнейшего углубленного изучения и использования, потому просто старался сделать одинаковую формулу для каждого кейса, оптимизация и верность самой формулы не цель. Пока , на данный момент самая бырая это ручная векторизация, что видно по тестам.

PS "Нет выравнивания! Для sse обязательно выравнивать.":depressed::wacky::bag: Уйду в ассембер чую. Я его давным давно лет в 16 пытался учить. Там все через выверт мозга, зато всерьез, однозначно и надолго.

Я кстате пробовал сделать ассемблерную вставку через "_asm" но меня VS матюкнула и отказалась компилить. Вообще стоит поковырять это дело, есть смысл пользовать ассемблер, в майских плагах под трасфрмы или деформеры по сути самих формул не так то и много. Мне вообще написание нод под майку японскую порнуху напоминает, 95% хмуренья бровей и жужжания всякими девайсами и 5% самой сути.
 

Вложения

Последнее редактирование:

Andots

Знаток
Рейтинг
66
#94
Сегодня переписал код под приложение чтоб уйти от майки. И дал более жизненную задачу. 9 массивов по 2097152 из которых по формуле пишется 4й.

Вот только результаты странные

Попытался разложить под SSE (в формуле правда ошибся но не суть, кол - во операций тоже самое) Прироста 0, даже медленнее стало.
АМР вообще тащиться в конце
Если будет время и желание глянь, мож что увидишь ; В архиве исходник и скомпиленый экзешник
Ну и сами результаты
---Размер массивов-- : 2097152
________________________Проверка значений_______________________________________
x = 27.6 : y = 22.8 :z = 18
*******************************************************************
Стандартный алгоритм без многоядерности
---Время выполнения-- : 0.044сек
________________________________________________________________________________

________________________Проверка значений_______________________________________
x = 27.6 : y = 22.8 :z = 18
*******************************************************************
Стандартный алгоритм с многоядерностью
---Время выполнения-- : 0.013сек
________________________________________________________________________________

________________________Проверка значений_______________________________________
x = 12 : y = 26.4 :z = 108.48
*******************************************************************
SSE с Многоядерностью
---Время выполнения-- : 0.013сек
________________________________________________________________________________

________________________Проверка значений_______________________________________
x = 12 : y = 26.4 :z = 108.48
*******************************************************************
SSE с Одноядерный
---Время выполнения-- : 0.06сек
________________________________________________________________________________

Девайс:
NVIDIA GeForce GTX 780
___________________________________________
________________________Проверка значений_______________________________________
x = 27.6 : y = 22.8 :z = 18
*******************************************************************
AMP алгоритм
---Время выполнения-- : 0.072сек
________________________________________________________________________________
Копирование в память 0.006сек
Арифметика 0.05сек

test.zip
 

Вложения

  • 50,2 КБ Просмотров: 377
Последнее редактирование:

4i4ikov

Знаток
Рейтинг
37
#95
Сегодня переписал код под приложение чтоб уйти от майки.
Зря, нормально не посмотреть, вызовы все раскиданы, язык русский, ориентировался только по clock(), и Ида ругается на кривизну. Надо было делать всё в одной процедуре, через case.
То что посмотрел - там всё через AVX, интрисики SSEшные не нашёл.
Но мне ломает это говно разгребать, ты учишься, я мучишься, сам и смотри что у тебя компилится, ИДА поставь и разглядывай сам свои анализы)
Через дебажку в принципе тоже можно смотреть, Ида хороша тем что сишный псевдокод делает, это поудобней.

Матчасть учи.
Выравнивание sse это базовые знания.

Про компиляцию интрисиков почитай, может потому и просадка по скорости, что оптимицации не было: https://msdn.microsoft.com/ru-ru/library/26td21ds(v=vs.100).aspx

И если руками хочешь оптимизировать sse/avx обязательно смотри особенности ILP (Instruction level parallelism) Как команды паралелялятся по конвееру, как это оптимизировать, деление например дорогая команда, умножение дешёвая и может за один такт проскочить. Компилятор в первом случае без векторизации сделал оптимизацию по ILP, это до 4x команд одновременно у Сандика, когда ты сам пишешь на асме, то оптимизацию ILP самому надо делать. Интрисики должны в принципе оптимизироваться компиляторм.
Про систему память-кэш тоже не помешает почитать, это касаемо вырвнивания.

Но я бы на твоем месте переключился на гпу, так как и то и то ты с нуля начинаешь. ГПУ по любому быстрее будет, только не на этом примере конечно, надо пример брать где вычислительная часть большая.
 

Andots

Знаток
Рейтинг
66
#96
Спасибки. Так наверно и сделаю, по сути особо ковырять avx или sse смысла нет, судя по всему автоматом все и так векторизуется, и в любом случае большого прироста не будет при ручной векторизации. Есть смыл разбираться в гпу.
 

4i4ikov

Знаток
Рейтинг
37
#97
Удалил, показалось что omp написан с ошибкой, нет всё верно и результы сходятся.

Ну при ручной оптимизации прирост может очень хороший быть, трудозатраты только больше.
Известный пример ручника:
Симметричный ГОСТ на AVX командах.doc
или отсюда https://vk.com/id184633937?w=wall184633937_102/all
Эта статья в куцаном виде была на Хацкере под названием "Хардкорный путь к производительности", в доке она полностью.
 
Последнее редактирование:

Andots

Знаток
Рейтинг
66
#98
Хм, по ссылке " 404 not found", а почитать было бы интересно, для небольших формул самое то, понятно что в большом проекте это целый гемор, но в отдельно взятом кастомном майском плаге можно долго не спеша ковыряться.

Нашел статью на хацкере.
 

4i4ikov

Знаток
Рейтинг
37
#99
Хм, по ссылке " 404 not found", а почитать было бы интересно, для небольших формул самое то, понятно что в большом проекте это целый гемор, но в отдельно взятом кастомном майском плаге можно долго не спеша ковыряться.

Нашел статью на хацкере.
Да, если сменить айпи и у меня тоже будет 404. Поправлю сейчас.
На Хацкере она без картинок и примеров.
 
Сверху