Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.93
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
#1

Программирование под GPU: Вычисление произведения матрицы на вектор - C++

15.05.2014, 14:56. Просмотров 2526. Ответов 32
Метки нет (Все метки)

Доброго времени суток!Ветку, связанную с программированием на ГПУ не нашел, пишу сюда.
проблема следующая. Есть код на С++ под ЦПУ и код на С++ под ГПУ для вычисления произведения матрицы на вектор.
По идее на ГПУ вычисления должны распараллеливаться, но возникает ситуация такая, что код, вычисляемын на ЦПУ работает быстрее. С чем бы это связано. В качестве библиотеки по ГПУ использовал CUDA и C++ AMP.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2014, 14:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Программирование под GPU: Вычисление произведения матрицы на вектор (C++):

Сформировать вектор B, компонентами которого являются произведения отрицательных элементов строк матрицы A - C++
Дана матрица A размерности N*N Сформировать вектор B(N), компонентами которого являются произведения отрицательных элементов строк...

Вычисление суммы и произведения элементов матрицы, находящихся на главной диагонали - C++
Задана квадратная матрица размером к на к, составить программу вычисления суммы и произведения элементов матрицы, находящихся на главной...

Вычисление степени матрицы, вычисления произведения двух матриц, вычисление суммы двух матриц - C++
Здравствуйте, помогите решить, пожалуйста: Заданы две квадратные матрицы А и В. Вычислить матрицу...

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

Матрицы. Получить вектор X, равный P-й строке матрицы, и вектор Y, равный Q-му столбцу матрицы - C++
1. Дана матрица A (3 х 5). Получить вектор X, равный P-й строке матрицы, и вектор Y, равный Q-му столбцу матрицы. P и Q запросить у...

Найти разность произведения нечетных чисел 3-ей строки и произведения отрицательных чисел 1-го столбца матрицы - C++
Найти разность произведения нечетных чисел 3-ей строки и произведения отрицательных чисел 1-го столбца матрицы В(4,4).

32
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
20.05.2014, 21:51  [ТС] #16
newbie666, GPU у меня nvidia geforce, я же привел код одной и той же функции тремя способами, приведу еще разок. Код функции умножения матрицы на вектор на GPU, выполняемый с помощью С++ AMP:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void getAnyMatrMV(float* matr,float* vctrRe1,float* vctrIm1,int kolQbs){
        int rzm=getRazm(kolQbs);
        DWORD xxx=GetTickCount();
        array_view<float,1> x(rzm,vctrRe1);
        array_view<float,1> x1(rzm,vctrIm1);
        float* vctRtrnRe=new float[rzm];
        float* vctRtrnIm=new float[rzm];
        array_view<float,1> y(rzm,vctRtrnRe);
        array_view<float,1> y1(rzm,vctRtrnIm);
        array_view<float,1> mrc(rzm*rzm,matr);
        //concurrency::extent<1> e(rzm);
        //mrc.discard_data();
        parallel_for_each(mrc.extent, [=](index<1> i) restrict(amp)
        {
            float res=0,res1=0;
            for(int k = 0; k < rzm; k++)
            {
            res+=x(k)*mrc(i*rzm+k);
            res1+=x1(k)*mrc(i*rzm+k);
            }
            y(i)=res;
            y1(i)=res1;
        });
        y.synchronize();
        y1.synchronize();
        y.copy_to(x);
        y1.copy_to(x1);
        DWORD yyy=GetTickCount();
        cout<<yyy-xxx<<endl;
        //getTOG(vctRtrnRe,vctRtrnIm,vctrRe1,vctrIm1,rzm);
    }
Код той же функции, но выполняемый на CPU:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
getAnyMatrM(float* matr,float* vctrRe1,float* vctrIm1,int kolQbs){
        int rzm=getRazm(kolQbs);
                DWORD xxx=GetTickCount();               
int j=0;
        int k=0;
        float*vctrRe=new float[rzm];
        vctrRe[0]=0;
        float*vctrIm=new float[rzm];
        vctrIm[0]=0;
        
        for(int i=0;i<rzm*rzm;i++){
            vctrRe[j]=vctrRe[j]+vctrRe1[k]*matr[i];
            vctrIm[j]=vctrIm[j]+vctrIm1[k]*matr[i];
            
            if((i+1)%rzm!=0){
                k++;
            }else{
                j++;k=0;
                if(j<rzm){
                    vctrRe[j]=0;
                    vctrIm[j]=0;
                }
            }
        }
        for(int i=0;i<rzm;i++){
            vctrRe1[i]=vctrRe[i];
            vctrIm1[i]=vctrIm[i];
        }
DWORD yyy=GetTickCount();
        cout<<yyy-xxx<<endl;
    }
И вот код, который выполняется так же на GPU с помощью CUDA вместе c вызовом этой фенкции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
extern "C" __declspec(dllexport) __global__ void MatrVectMul(float *re,float* im, float *matr,int rzm)
{
    int i = blockIdx.x*blockDim.x+threadIdx.x;
    float sum,sum1;
    if(i<rzm)
    {
    sum=0,sum1=0;
    for (int k=0;k<rzm && i<rzm;k++){
        sum+=matr[i*rzm+k]*re[k];
        sum1+=matr[i*rzm+k]*im[k];
    }
    re[i]=sum;
    im[i]=sum1;
    }
}
extern "C" __declspec(dllexport) void getAnyMatrM(float *vctrRe,float *vctrIm, float *matr,int rzm){
    float *vctrReV,*vctrImV,*matrV;
    // выделение видеопамяти
    cudaMalloc((void **)&vctrReV, sizeof(int)*rzm);
    cudaMalloc((void **)&vctrImV, sizeof(int)*rzm); 
    cudaMalloc((void **)&matrV, sizeof(int)*rzm*rzm);
// копирование из оперативной памяти в видеопамять
    cudaMemcpy(vctrReV, vctrRe, sizeof(int)*rzm, cudaMemcpyHostToDevice);
    cudaMemcpy(vctrImV, vctrIm, sizeof(int)*rzm, cudaMemcpyHostToDevice);
    cudaMemcpy(matrV, matr, sizeof(int)*rzm*rzm, cudaMemcpyHostToDevice);
    // установка количества блоков
    dim3 grid((rzm+255)/256, 1, 1);
    // установка количества потоков в блоке
    dim3 threads(256, 1, 1);
    MatrVectMul<<< grid,threads>>> (vctrReV,vctrImV,matrV,rzm);
    //Синхронизируем с моментом окончания расчетов
    cudaMemcpy(vctrRe, vctrReV, sizeof(int)*rzm, cudaMemcpyDeviceToHost);
    cudaMemcpy(vctrIm, vctrImV, sizeof(int)*rzm, cudaMemcpyDeviceToHost);
    // освобождение памяти
    cudaFree(vctrReV);
    cudaFree(vctrImV);
}
Добавлено через 52 секунды
Оба GPUшных кода выполняются медленне CPUшного
0
newbie666
Заблокирован
20.05.2014, 22:08 #17
Цитата Сообщение от iltat Посмотреть сообщение
Оба GPUшных кода выполняются медленне CPUшного
а как ты это определил?

А так, мне лень вчитываться в кучу строк... так, на первый взгляд ты плохо шаришь в оптимизации алгоритмов и собственно в самом CUDA тоже и скорее всего у тебя просто напросто uncoalescing memory read/ write, сам цикл завтра на работе вnvidia nsight-е гляну, так и быть, раз тебе влом его устанавливать...

А пока, тебе советую, попробовать поиграть на простых примерах, например на умножение каждого элемента обычного массива интов на какое - то значение и посмотреть, где быстрее выполняется. Если на GPU - быстрее - значит у тебя в твоём основном коде плохой алгоритм GPU кода...
И ещё, какой ИМЕННО у тебя GPU и CPU...
P.S.: ты слышал про оптимизацию кода на С++ компилятором?
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
20.05.2014, 23:23  [ТС] #18
так я определяю время выполнения
C++
1
2
3
DWORD xxx=GetTickCount();
DWORD yyy=GetTickCount();
t=yyy-xxx;
CUDA Nsight у меня стоит
про оптимизация компилятором не слышал) просветите

Добавлено через 54 минуты
newbie666, а может ли быть так, что проблема в слабости самой GPU?

Добавлено через 4 минуты
newbie666, я попробовал реализовать задачу умножения матрицы на число, там все нормально, т.е. при размерности матрицы = 1024 время выполнения на GPU меньше, чем на CPU. Однако при компилировании в NSIGHT опять та же проблема
0
newbie666
Заблокирован
21.05.2014, 08:09 #19
Цитата Сообщение от newbie666 Посмотреть сообщение
И ещё, какой ИМЕННО у тебя GPU и CPU...
???
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 10:57  [ТС] #20
newbie666, core i2 - cpu, nvidia geforce - gpu
0
newbie666
Заблокирован
21.05.2014, 10:58 #21
Цитата Сообщение от iltat Посмотреть сообщение
nvidia geforce - gpu
Пфф.... какой именно бл.... ?

Этот код ты писал?

Весь проект выкладывай в архиве
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 19:48  [ТС] #22
newbie666, да,я писал. Версию не могу посмотреть,т.к. ноут нк под рукой. Вечером все скину, и проект тоже

Добавлено через 8 часов 36 минут
newbie666, gpu - g105m

Добавлено через 13 секунд
newbie666, gpu - g105m
0
newbie666
Заблокирован
21.05.2014, 20:37 #23
Цитата Сообщение от newbie666 Посмотреть сообщение
Этот код ты писал?
??

сломанный телефон какой- то... ГДЕ АРХИВ С ПРОЕКТОМ?
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 21:21  [ТС] #24
интернет туповатый, через гсм-модем сижу. как тут файл-то закинуть?или можно только через файлообменник?
0
newbie666
Заблокирован
21.05.2014, 21:36 #25
снизу смотри - рядом с отправить быстрый ответ есть "расширенный режим" - далее - управление вложениями и тд

Добавлено через 9 минут
не забудь всякие не нужные файлы студии потереть, которые занимают хрен знает сколько места ... оставь только код и файлы проекта с директориями, завтра с утра на работе гляну, там у меня студия с nvsight_ом...дома нету
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 21:43  [ТС] #26
вот, наконец)
0
Вложения
Тип файла: rar CudaQuLib - копия.rar (2.90 Мб, 10 просмотров)
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 21:44  [ТС] #27
newbie666, не успел, все скинул)
0
newbie666
Заблокирован
21.05.2014, 21:45 #28
Цитата Сообщение от iltat Посмотреть сообщение
не успел, все скинул)
у меня ща компилятора CUDA под рукой нет, завтра, на работу приползу часикам к 11-и, тами сразу посмотрю и протещу в NSIGHT профайлере твой чудо софт
0
iltat
0 / 0 / 0
Регистрация: 15.05.2014
Сообщений: 17
21.05.2014, 21:48  [ТС] #29
ок, спасибо)
0
newbie666
Заблокирован
22.05.2014, 13:31 #30
У меня пока что времени нет особо копаться подробно... Ну а что тебя не устраивать? Тыж не прикрепил проект на CPU, я б сравнил, где быстрее, а где медленнее... У меня твоя функция выполняется меньше меньше чем за 1-у миллисекунду
Так, на вскидку, основное время у тебя занимает копирование памяти в GPU (нон каолескинг) ...
Что тебе сравнивать то надо? Прикрепляй два проекта - одни на GPU, другой на CPU - сравню
0
Миниатюры
Программирование под GPU: Вычисление произведения матрицы на вектор  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.05.2014, 13:31
Привет! Вот еще темы с ответами:

Вычисление произведения - C++
Доброго время суток. Написать программу вычисления произведения: \prod_{1}^{\propto}\cos(\frac{\pi }{{2}^{(n+1)}}) = \frac{2}{\pi } ...

Вычисление произведения - C++
Здравствуйте. Мне проблема в том, что я не знаю как написать код по данным примерам. Не могли бы вы помочь, и скинуть литературу. ...

Вычисление произведения сумм - C++
t=\prod_{a=1}^{5}\sum_{b=1}^{10}cos\,ab Помогите пожалуйста я не очень знаю с++ буду благодарен

Вычисление конечного произведения - C++
Всем Доброго времени суток! Имеется задача: Вычислить произведение \sum_{n=1}^{k} (1+\frac{x^n}{2n!}) Я сделал данную программу, заведя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
22.05.2014, 13:31
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru