Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 15.09.2015
Сообщений: 3

Распараллеливание рекурсивного метода

09.08.2016, 10:54. Показов 2377. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Реализую метод медианного сечения квантования изображений:
http://www.intuit.ru/studies/c... 513?page=3

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

Сейчас метод выглядит так:

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
private static void Algorithm(Pixel[] array)
        {
       
            if (array.Length <= ArrayLen / 65536)
            {
                //усреднение значений цветовых каналов в массиве и их вывод за пределы функции
            }
 
            else
            {
                Pixel[] newArray1 = new Pixel[array.Length / 2],
                newArray2 = new Pixel[array.Length / 2];
 
 
                SortPixels(ref array, GetSortOrder(array)); //сортировка массива по каналу с наибольшим range
 
                newArray1 = array.Take(array.Length / 2).ToArray();
                newArray2 = array.Skip(array.Length / 2).ToArray();
 
 
                Task thread1 = Task.Factory.StartNew(() =>
                {
                    Algorithm(newArray1);
                });
                Task thread2 = Task.Factory.StartNew(() =>
                {
                    Algorithm(newArray2);
                });
 
                
            }
        }
Производительностью доволен: всё работает очень быстро (всего 7 секунд для 4к изображения не на самом сильном ноутбучном процессоре); но почему-то приложение продолжает выполняться после даже вывода изображения (которое происходит после вызова функции) и кушать память в течение достаточно долгого времени. Что я делаю не так?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.08.2016, 10:54
Ответы с готовыми решениями:

Модификации для рекурсивного метода
Написать рекурсивный метод DigitSum(K) целого типа, который находит сумму цифр целого числа K, не используя, оператор цикла. Модификация...

Исправить реализацию рекурсивного метода
Подскажите плиз, Что здесь неправильно using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

Распараллеливание метода
Пытаюсь распаралелить добавление эдементов в ListView, так как обработка больших файлов занимает довольно много времени. Но поскольку в С#...

1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
09.08.2016, 16:38
Somaroton, а зачем вам новые массивы выделять? Работайте с одним, просто делите его на диапазоны и всё. Указываете для каждой операции начальный и конечный индекс.

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

Длину сегмента соответственно определяете не как "array.Length", а как "endIndex - startIndex".
Ну и рекурсию на цикл замените.
Array.Sort умеет сортировать не только весь массив, но и определенный диапазон - воспользуйтесь этим.

Добавлено через 1 минуту
Ну и да, вы запускаете таски, но не ждете окончания их выполнения (бросили и забыли), нужно ждааать.

Добавлено через 7 минут
По идее это должно выглядеть как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static async Task Algorithm(Pixel[] array)
{
    for (int segmentLength = array.Length; segmentLength > ArrayLen / 65536; segmentLength /= 2)
    {
        var sortTasks = new List<Task>();
        for (int startIndex = 0; startIndex < array.Length; startIndex += segmentLength)
        {
            int partitionEndIndex = Math.Min(array.Length, startIndex + segmentLength);
            sortTasks.Add(Task.Run(() => SortPixels(array, startIndex, partitionEndIndex, GetSortOrder(array, startIndex, partitionEndIndex)))); //сортировка массива по каналу с наибольшим range)
        }
 
        await Task.WhenAll(sortTasks);
    }
 
    //усреднение значений цветовых каналов в массиве и их вывод за пределы функции
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.08.2016, 16:38
Помогаю со студенческими работами здесь

Выход из рекурсивного метода не осуществляется по Return
Почему-то после return опять рекурсию повторяет, мб я неправильно её написал ? private string FileIndexCreate() { ...

Распараллеливание метода Якоби
Помогите пожалуйста распараллелить функцию Якоби для решения СЛАУ. Я вообще ничего не понимаю в параллелизме:( static void Jacobi1(int...

Перевод из рекурсивного метода в "обычный"
Перевод из рекурсивного метода. Нужно преобразовать программу в обычный вид. static void WriteNumber(int a) { ...

Перегрузка рекурсивного метода
Здравсвуйте. У меня два вопроса: 1) Почему происходит перегрузка метода max_coincidence? 2) Как обезвредить не меняя алгоритма? ...

Вывод рекурсивного метода
Всем привет. Собсно написал рекурсию для вычисления факториала. Проблема состоит с выводом. А именно в строке ...


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
Программный отбор значений справочника
Maks 21.03.2026
Установка программного отбора значений справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru