Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
1

GPU-based Parallel for beginner

23.02.2015, 05:59. Просмотров 1073. Ответов 13
Метки нет (Все метки)

Здравствуй!

Стоит задача переписать один оптимизационный алгоритм. Сделать его "GPU-based Parallel".
Тема довольно специфическая. Я вней полный нуб. Прошу помощи. Помоги начать. А то, если пойду по неправильному пути - трындец.

Особенно интересует нормальная проверенная литература.

Заранее спс!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2015, 05:59
Ответы с готовыми решениями:

Parallel.For
Кароче идея в чём, имееться готовая программа которая патрошит word файлы....

Проблемы с Parallel.For
Есть компьютер с 4 ядрами. Решил оптимизировать своё приложение для анализа...

Распараллеливание. Parallel.ForEach
На данный момент выполняется такой код: Hashtable files2copy; void...

Вопрос [Parallel Extensions]
Доброе время суток. Если вы использовали то помогите мне прекрутить это. Я...

StackOverflow при использовании Parallel.For
Привет. Есть некая рекурсия, которая считает связанные элементы в 3д массиве...

13
_lunar_
1451 / 1367 / 185
Регистрация: 03.05.2011
Сообщений: 3,172
Завершенные тесты: 1
23.02.2015, 11:12 2
Лучший ответ Сообщение было отмечено some_name как решение

Решение

распараллелить код на GPU на шарпе можно с помощью OpenCL, который входит в состав OpenTK (ну или CUDAfy.NET).
а на CPU распараллелить код можно с помощью PLINQ и работа с PFX
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
23.02.2015, 14:09 3
Лучший ответ Сообщение было отмечено some_name как решение

Решение

some_name, посмотри в сторону С++ AMP и PInvoke
0
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
23.02.2015, 14:16  [ТС] 4
_lunar_, спасибо. Начало положено.

Psilon, спасибо. Пока что буду иметь ввиду, т.к. сам алгоритм на C#. Думаю сложновато будет его на C++ переписывать. Хотя... "unsafe code" в помощь.
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
23.02.2015, 16:15 5
some_name, вот ссылка, может помочь:
http://habrahabr.ru/post/131372/

Если вы для себя делаете, то .net-средства дают очень слабый прирост производительности.
http://rsdn.ru/article/dotnet/CudaLibs.xml

всего лишь 2-3 раза относительно CPU, того же можно добиться просто используя SIMD.
0
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
03.06.2015, 17:59  [ТС] 6
Цитата Сообщение от Psilon Посмотреть сообщение
Если вы для себя делаете, то .net-средства дают очень слабый прирост производительности.
http://rsdn.ru/article/dotnet/CudaLibs.xml
Здравтвуйте! Странная штука. По этой ссылке, что Вы дали. Автор сравнил несколько библиотек для распараллеливания на GPU. Так вот, я решил последовать его совету и выбрал для себя Accelerator v2. Но нигде не могу найти по ней информации. Даже на здесь - пару слов о ней, ссылки есть, но толку 0. Так как страницы такой нету. Nuget тоже ее найти не может. Беда вообщем.
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
03.06.2015, 18:26 7
some_name, юзайте C++ AMP и будет счастье. Благо интероп с С++ очень простой, особенно по сравнению по распараллеливанию алгоритмов, до пригодного для gpgpu уровня параллелизации
0
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
03.06.2015, 18:36  [ТС] 8
Psilon, видимо придется. Делать-то нечего. А вы не вкурсе что с эти проктом стало? У меня не получилось найти информацию.
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
03.06.2015, 18:37 9
some_name, скорее всего они потому и скурвились, что амп намного лучше, но ничуть не сложнее. Немного интеропа добавляется, но это вопрос привычки, а не сложности.
0
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
03.06.2015, 19:47  [ТС] 10
Psilon, а что вы можете сказать про CUDAfy.NET? Дело в том, что код написан на C# и мне бы не очень хотелось переписывать его на С++. Плюс ко всему, мне необходимо выполнять на GPU параллельные вычисления в разных варпах(что-то вроде потоков для CPU). Вот здесь описано то, что я хочу сделать.
*в двух словах: У меня есть L точек в n-мерном пространстве. И мне нужно каждую точку перемещать в этом пространстве. И эти перемещения должны быть выполнены в отдельных варпах. Т.е. для каждой точки свой варп. C++ AMP позволит такое проделать?
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
03.06.2015, 20:44 11
some_name, при чем тут переписывать на С++? НА С++ вы пишете 1-2 функции, которые у вас сжирают время, всё остальное на шарпе. В этом и смысл интеропа.

С++ АМР просто ускоряет ваш алгоритм на ГПУ, алгоритм вы сами придумываете/списываете с книжки. Насчет позволяет - не понял, любой алгоритм можно написать на чем угодно, лишь бы он был.
0
some_name
Вежливость-главное оружие
227 / 226 / 86
Регистрация: 19.02.2013
Сообщений: 1,441
03.06.2015, 22:18  [ТС] 12
Цитата Сообщение от Psilon Посмотреть сообщение
Насчет позволяет - не понял
Я имел ввиду можно при помощи C++ AMP для каждой из L точек создать варп на GPU?

И еще нюанс. У меня есть множество функций(обычные математические функции, которые нужно оптимизировать. например ф-я Розенброка и т.д.), которые представлены неким объектом Problem. Если я напишу эти фукции на c++ AMP в виде отдельной библиотеки. То при добавлении новой функции - придется пересобирать библиотеку. Это очень плохо.

Все что мне нужно распараллелиить - так это функцию класса Problem - CalculateQualitie.

Как мне лучше поступить?
0
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
04.06.2015, 13:25 13
some_name, в смысле пересобирать библиотеку? Розенброк принимает на вход делегат, в С++ можно попробовать передавать указатель на функцию, я лично с такими извращениями не сталкивался, но например тут пишут, что возможно:
http://stackoverflow.com/questions/7...nterop-pinvoke

соответственно у вас ваш класс остается шарповым, а все самые затратные функции выносятся как static export функции, которые имплементированны в С++ библиотеке.

Добавлено через 17 минут
Вот набросал примерчик
0
Вложения
Тип файла: zip CppDelegateInterop.zip (209.7 Кб, 1 просмотров)
Psilon
Master of Orion
Эксперт .NET
6003 / 4853 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
04.06.2015, 13:33 14
some_name, вот например я когда-то делал как раз розенброка, там никаких проблем вынести что-то тяжелое на ГПУ, отдельные методы например:
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Collections.Generic;
 
namespace Model
{
    public enum OptimizationDirection
    {
        ToMin,ToMax
    }
 
    public class Rosenbrock
    {
        private readonly Func<double[], double> f;
        private readonly double epsilon;
        private Vector y;
        private Vector[] d;
        private readonly int n;
        private readonly List<IterationDetails> details = new List<IterationDetails>();
        public OptimizationDirection Direction = OptimizationDirection.ToMin;
 
        public IEnumerable<IterationDetails> Details { get { return new List<IterationDetails>(details); } }
 
        public Rosenbrock(Func<double[], double> f, Vector startPoint, double epsilon)
        {
            if (startPoint.IsEmpty)
                throw new ArgumentException("startPoint");
            n = startPoint.Length;
            this.f = x => Direction == OptimizationDirection.ToMin ? f(x) : -f(x);
            this.epsilon = epsilon;
            y = startPoint;
            d = new Vector[n];
            for (int i = 0; i < n; i++)
            {
                d[i] = new Vector(n);
                d[i][i] = 1;
            }
            SmartPoint.SetFunction(f);
        }
 
        public Vector Solve()
        {
            int k = 0;
            details.Clear();
            var lambda = new Vector(n);
            Vector previousIterationY;
            do
            {
                k++;
                previousIterationY = y;
                var iterDetails = new IterationDetails(y, k);
                for (int j = 0; j < n; j++)
                {
                    var previousStepY = y;
                    int i = j;
                    lambda[j] = Dichotomy(x => LambdaSolve(x, i), y[j]);
                    y += lambda[j] * d[j];
                    iterDetails.Add(new StepDetails(previousStepY, lambda[j], d[j], y, i+1));
                }
                details.Add(iterDetails);
                d = GramSchmidtProcess(lambda);
            } while ((y - previousIterationY).Norm >= epsilon);
            return y;
        }
 
        private double LambdaSolve(double x, int j)
        {
            return f(y + x * d[j]);
        }
 
        private Vector[] GramSchmidtProcess(Vector lambda)
        {
            var a = new Vector[n];
            for (int j = 0; j < n; j++)
                if (Math.Abs(lambda[j]) < epsilon) //Если ноль
                    a[j] = d[j];
                else
                {
                    a[j] = new Vector(n);
                    for (int i = j; i < n; i++)
                        a[j] += lambda[i] * d[i];
                }
            var b = (Vector[])a.Clone();
            b[0].Normalize();
            for (int j = 1; j < n; j++)
            {
                for (int i = 0; i < j; i++)
                    b[j] -= Vector.TransposeAndMultiply(a[j], b[i]) * b[i];
                b[j].Normalize();
            }
            return b;
        }
 
        private double Dichotomy(Func<double, double> func, double startCoord)
        {
            double deviation = Math.Abs(startCoord) < double.Epsilon ? 5 : Math.Abs(startCoord) * 0.5 + 10;
            double a = startCoord - deviation, b = startCoord + deviation;
            double delta = epsilon / 10;
            while (b - a >= epsilon)
            {
                double middle = (a + b) / 2;
                double lambda = middle - delta, mu = middle + delta;
                if (func(lambda) < func(mu))
                    b = mu;
                else
                    a = lambda;
            }
            return (a + b) / 2;
        }
    }
}
Тут есть ненужное логгирование, ну и код по большому счету переделывать много где надо, но идея именно такая, вызывается для произвольной функции.
0
Вложения
Тип файла: zip VectorOptimization.zip (1.25 Мб, 1 просмотров)
04.06.2015, 13:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2015, 13:33

PLINQ или Parallel.ForEach?
Пытаюсь сообразить как лучше сделать задачку. Есть большой список EXCEL файлов...

Parallel.NET и ref параметры
Есть код перемножения матриц, но ref данные нельзя использовать внутри...

Потокобезопасная коллекция для Parallel.For
Какой список выбрать для Parallel.For? Например в коллекции 1000 элементов....


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

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