![]() |
||||||||||||||||
Оптимизация производительности C#.NET (Алгоритм, Многопоточность, Debug, Release, .Net Core, Net Native)26.03.2017, 13:39. Показов 5003. Ответов 19
Метки нет Все метки)
(
Решил поделится своим небольшим опытом по оптимизации вычислений на C#.NET.
НЕ профи, палками не кидать, конструктив приветствуется! Тестом будет служить время вычисление всех переменных в заданном диапазоне (до 100000) в уравнении x^3 + y^3 = z^3 - 1 Симметричные решения по x и y не учитываем, т.е. из вариантов х=6,у=8,z=9 и х=8,у=6,z=9 - берем один (любой). Оборудование/Софт: Кликните здесь для просмотра всего текста
Тип ЦП QuadCore AMD Phenom II X4 Black Edition 955, 3200 MHz (16 x 200)
Системная плата Asus M4A89GTD Pro (2 PCI, 1 PCI-E x1, 1 PCI-E x4, 2 PCI-E x16, 4 DDR3 DIMM, Audio, Video, Gigabit LAN, IEEE-1394) Чипсет системной платы AMD 890GX, AMD K10 Системная память 8192 МБ (DDR3-1333 DDR3 SDRAM) Софт Win10x64, Excel2016x64, Visual Studio 2017 ШАГ1. Все кажется просто, берем и перебором ищем значения. Здесь сражу же упираемся в большое количество итераций - время выполнение неприлично большое. Поэтому ШАГ2 - Оптимизируем алгоритм, создаем массив из степеней Z, переберем значения х, у, обрезаем ненужные итерации, оставляем только один вариант x,y и обрезаем итерации на суммах x^3 + y^3 > z^3. Здесь (код) пальма первенства справедливо принадлежит m-ch - опять неприлично долго в VBA более 10 мин. ШАГ3. Берем этот алгоритм, переносим на C# и делим потоки, благо это задача хорошо бьется по потокам. Код (Сборка Debug x64): Кликните здесь для просмотра всего текста
Время выполнения чуть более 4 минут (по ссылке выше есть так же расчет и на Freebasic). Пока прохладно. ШАГ4. В C# (как проверено и не только в C#) расчет корня 3 степени медленнее, чем прямой перебор в массиве с некоторой хитростью (т.к. он отсортирован и перебор всегда ведется от меньшего к большему, или наоборот, легко запоминать последнюю найденную позицию и искать начиная с неё в след. цикле). Эта мысль меня посетила и была сразу реализована. Код (Сборка Debug x64) - делю на 4 потока, т.к. больше для моего ЦП -нет смысла: Кликните здесь для просмотра всего текста
Время выполнения - 41 сек. Уже теплее. ШАГ5. Как же я забыл про Release, срочно исправляюсь - Сборка Release x64. За счет оптимизации при компилировании получаем время выполнения - 17 секунд. Уже тепло. Появляются мысли про оптимизацию цикла (в сети множество советов и примеров), т.к. для вычисления требуется несколько миллиардов итераций. Думаю. ШАГ6. Почитав про .Net Core, решил попробовать. Новый проект - Консольное приложение .Net Core - вставляем предыдущий код и ... Время выполнения - 10,5 сек. Здесь мне кажется, что сделан максимум на C#. ШАГ7. Решил добить тему и погуглить. Есть интересный зверь net native, подробно писать здесь не буду. Кратко: В Windows 10 универсальные Windows-приложения на управляемых языках (C#, VB) проходят в магазине процедуру компиляции в машинный код с использованием .NET Native. Поэтому: создать проект-пустое приложение (универсальное приложение Windows)(UWP). Создаем button, textBox (на кнопку код, в textBox - переменные). Здесь нас поджидает проблемы с Threading. Переходим на Task, двигаем дальше. Код (Сборка Release x64) Кликните здесь для просмотра всего текста
Время выполнения 7,5 сек. Без вывода строки 5 сек.(подумать со строкой) ШАГ8. АССЕМБЛЕР... здесь мои знания заканчиваются... Что скажут ОТЦЫ, есть ли дальнейшая оптимизация? В блоге.
0
|
26.03.2017, 13:39 | |
Ответы с готовыми решениями:
19
Объясните на пальцах совместимость библиотек в .Net Core, .Net Framework, .Net Standart Разница между ASP.NET Core 2, ASP.NET Core MVC, ASP.NET MVC 5 и ASP.NET WEBAPI 2 Сравнение производительности MariaDb и PostgreSql на .NET CORE |
![]() 601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
|
|||||||||||||||||||||||||||||||||||||||||
26.03.2017, 19:02 | |||||||||||||||||||||||||||||||||||||||||
bedvit, я не батька, поэтому напишу здесь.
В общем, проверил этот же код на своем компьютере, немного изменив, выдает следующие результаты: На 4 ядра:
Код
Затем решил поискать варианты с кодов, где реализован интерфейс TaskScheduler В итоге, вроде как, не чего не изменилось:
Код с TaskScheduler
Ну и на ресурсе itvdn есть свои примеры с реализацией этого интерфейса, но они выкидывают наллреференс, через раз =)) Проверил на 4 ядрах, на 8 не вышло без исключений.
Код с классов с ресурсов itvdn
Еще один класс с itvdn
1
|
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
26.03.2017, 20:47 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Все возможные значения на текущем алгоритме (с int64). Отсортировано по Z. Итого 84 решения. Диапазон переменных 1:2097151((2^63)^(1/3)-1). См.под спойлер
Кликните здесь для просмотра всего текста
конфигурация та же, 4 ядра и т.д. (см. выше) Расчет по алгоритму ШАГ6 - 1час 29мин. По алгоритму ШАГ7 через (универсальное приложение Windows)(UWP) и компиляцию в машинный код, на таких больших диапазонах вылетает ошибка - причину пока не определил. Добавлено через 2 минуты А понять хочется ибо этот алгоритм/способ у меня самый быстрый сейчас. Добавлено через 3 минуты EveKS, насколько я понял, вы тоже через Console .Net Core, не через (универсальное приложение Windows)(UWP)?
0
|
![]() 601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
|
|||||||||||||||||||
27.03.2017, 08:41 | |||||||||||||||||||
bedvit, еще немного оптимизировал текущий алгоритм, ниже результат на 8 и 4 ядрах:
Код
// ************* Нужно вкорне менять подход, т.к. переборы от 1 до нужного числа, не есть хороше. Возможно, стоит посмотреть в сторону деревьев или поискать другое решение. Не по теме: Вчерашний комент связан с недопониманием :)
0
|
![]() |
|
27.03.2017, 11:59 [ТС] | |
Срастается, потому как диапазон переменных взят больше - до 2097151. Вы и сами наверное уже поняли, судя по последнему коменту
![]() Пока алгоритм сильно улучшить не удалось.
0
|
![]() 601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
27.03.2017, 12:59 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bedvit, делать было нечего, решил дальше тестить, что да как:
Первые два варианта, вроде как дали маленький плюс, но не большой, выложу результаты на 4 ядра: 4 ядра, 2 варианта
Здесь я изменял только метод
Но, в итоге, на данный момент, этот вариант выдает самые быстрые результаты, но с ошибкой в решении, и этому есть причина. Тесты на 8 и 4 ядрах:
Текущий код метода
Весь код
А теперь, о том об ошибке в вычислении: X всегда получается на 1 больше, чем нужно, из-за x++;. Y и Z верны(но всегда-ли это будет). Стоит убрать x++;, и решение становится верным, но время выполнения становится больше чем с x++; Результаты тестов без x++;
И этого мало, казалось бы, если посмотреть весь код, то эту часть:
Но и тут нелепость, время выполнения становится дольше ![]() как не странно:
![]() Результаты тестов с long x = start;
0
|
![]() |
|
27.03.2017, 13:41 [ТС] | |
EveKS, на первый взгляд странно. У вас не Win10 случаем? Хочу понять почему вариант/ШАГ7 не хочет работать на больших диапазонах переменных. Дело в компиляции или я чего-то не знаю/не учитываю. Пока у меня этот самый быстрый вариант за счет компиляции в машинный код (диапазон переменных до 500-600 тыс. далее вылетает ошибка). И да, спасибо за тесты!
0
|
![]() ![]() 17812 / 12963 / 3381
Регистрация: 17.09.2011
Сообщений: 21,251
|
|||||||
27.03.2017, 14:40 | |||||||
В алгоритм не вникал, но можно малость производительности выжать, если убрать проверку индексов массива:
2
|
![]() 601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
|
||||||
27.03.2017, 15:45 | ||||||
kolorotur, интересно
![]() Вот что выдает у меня на 4 и 8:
0
|
![]() |
|||||||||||||||||||||
28.03.2017, 11:43 [ТС] | |||||||||||||||||||||
уже лучше
![]() Добавлено через 3 часа 17 минут На рабочем ПК (4 потока)
Добавлено через 16 часов 3 минуты Прогнал дома код через .Net Native, ожидаемого прироста не получил. Разница небольшая от .Net Core
0
|
![]() |
|
29.03.2017, 14:34 [ТС] | |
За инфо Спасибо, глянем.
Добавлено через 22 часа 27 минут Развернул данное решение на .NET Core (.exe). Методика. Итого стандартный вариант на netcoreapp1.1, win7-x64 - 50 метров. Сокращенный вариант на netstandard1.6, win7-x64 - 30 метров. Плата за автономность (и некоторый прирост скорости по отношению к .NET Framework). Добавлено через 2 часа 22 минуты Выходит следующее(Тип ЦП (рабочий) QuadCore Intel Core i7-3770, 3700 MHz (37 x 100) - 8 лог.ядер): С#.NET Core - 2.0 сек. (скорость+, переносимость-) С#.NET Framework - 5,6 сек. (скорость-, переносимость+)
0
|
29.03.2017, 15:42 | ||||||
Как измениться производительность, если вместо long z = 1; записать long z = x;?
Не нужно проверять весь массив с первого элемента, достаточно начинать с позиции x Добавлено через 4 минуты или
1
|
![]() 6524 / 4100 / 1606
Регистрация: 09.05.2015
Сообщений: 9,562
|
||
29.03.2017, 16:20 | ||
0
|
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
29.03.2017, 18:43 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
m-ch, сейчас проверим, Someone007, согласен с тем, что не везде есть Framework, но под win проблем нет (а вот .NET Core есть точно не на всей win), поэтом что бы поделится своим решение на С#.NET Core нужно переслать - 50 МБайт(.exe+библиотеки), что бы С#.NET Framework - 50 КБайт(.exe)
Если не под Win, ситуация конечно меняется. Поправьте, если что-то упускаю. Тестовый код: Кликните здесь для просмотра всего текста
Добавлено через 5 минут z = (long)(x * 1.2599) выигрывает: Кликните здесь для просмотра всего текста
Добавлено через 30 минут С#.NET Framework догоняет С#.NET Core, разница всего в 5% Была поднята мин. граница массива в переборе, видимо С#.NET Core быстрее обрабатывает большие массивы. Кликните здесь для просмотра всего текста
0
|
![]() |
|||||||||||
31.03.2017, 14:07 [ТС] | |||||||||||
Подведя промежуточные итоги, последний вариант решения на .NETCoreApp1.1 (благодаря EveKS,kolorotur,m-ch).
Кликните здесь для просмотра всего текста
Решение на NET Framework 4.0 (макс. охват на win), здесь немного доработал свой код из стартового сообщения. Незначительно проигрывает ![]() Кликните здесь для просмотра всего текста
0
|
![]() |
|
31.03.2017, 14:13 [ТС] | |
Зато компилируется в один .exe 7 Кб и работает почти на всех win.
0
|
![]() |
|
07.04.2017, 16:04 [ТС] | |
Причем на более слабом ПК, разрыв увеличился до 20%. Видимо, CLR использует лучше более быстрые(?) ЦП (возможно оптимальнее использует инструкции(?) чем С++ скомпилированный под все х64)
0
|
07.04.2017, 16:04 | |
Помогаю со студенческими работами здесь
20
ASP.NET Core. Старт - что нужно знать, чтобы стать ASP.NET Core разработчиком? Библиотека NETSquirrel для .NET и .NET Core - формат вывода индексаторов
Можно ли использовать библиотеки написанные на .net Core для .net FW Как подключить к ConsoleApp(.Net Core) библиотеку (.Net Standart) Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Опции темы | |
|
Новые блоги и статьи
![]() |
||||
Реализация многопоточных сетевых серверов на Python
py-thonny 16.05.2025
Когда сталкиваешься с необходимостью писать высоконагруженные сетевые сервисы, выбор технологии имеет критическое значение. Python, со своей элегантностью и высоким уровнем абстракции, может. . .
|
C# и IoT: разработка Edge приложений с .NET и Azure IoT
UnmanagedCoder 16.05.2025
Мир меняется прямо на наших глазах, и интернет вещей (IoT) — один из главных катализаторов этих перемен. Если всего десять лет назад концепция "умных" устройств вызывала скептические улыбки, то. . .
|
Гибридные квантово-классические вычисления: Примеры оптимизации
EggHead 16.05.2025
Гибридные квантово-классические вычисления — это настоящий прорыв в подходах к решению сложнейших вычислительных задач. Представьте себе союз двух разных миров: классические компьютеры, с их. . .
|
Использование вебсокетов в приложениях Java с Netty
Javaican 16.05.2025
HTTP, краеугольный камень интернета, изначально был спроектирован для передачи гипертекста с минимальной интерактивностью. Его главный недостаток в контексте современных приложений — это. . .
|
Реализация операторов Kubernetes
Mr. Docker 16.05.2025
Концепция операторов Kubernetes зародилась в недрах компании CoreOS (позже купленной Red Hat), когда команда инженеров искала способ автоматизировать управление распределёнными базами данных в. . .
|
Отражение в C# и динамическое управление типами
stackOverflow 16.05.2025
Reflection API в . NET — это набор классов и интерфейсов в пространстве имён System. Reflection, который позволяет исследовать и манипулировать типами, методами, свойствами и другими элементами. . .
|
Настройка гиперпараметров с помощью Grid Search и Random Search в Python
AI_Generated 15.05.2025
В машинном обучении существует фундаментальное разделение между параметрами и гиперпараметрами моделей. Если параметры – это те величины, которые алгоритм "изучает" непосредственно из данных (веса. . .
|
Сериализация и десериализация данных на Python
py-thonny 15.05.2025
Сериализация — это своего рода "замораживание" объектов. Вы берёте живой, динамический объект из памяти и превращаете его в статичную строку или поток байтов. А десериализация выполняет обратный. . .
|
Чем асинхронная логика (схемотехника) лучше тактируемой, как я думаю, что помимо энергоэффективности - ещё и безопасность.
Hrethgir 14.05.2025
Помимо огромного плюса в энергоэффективности, асинхронная логика - тотальный контроль над каждым совершённым тактом, а значит - безусловная безопасность, где безконтрольно не совершится ни одного. . .
|
Многопоточные приложения на C++
bytestream 14.05.2025
C++ всегда был языком, тесно работающим с железом, и потому особеннно эффективным для многопоточного программирования. Стандарт C++11 произвёл революцию, добавив в язык нативную поддержку потоков,. . .
|