-14 / 7 / 4
Регистрация: 24.02.2013
Сообщений: 234
1

Быстродействие управляемого и неуправляемого кода

19.06.2014, 07:56. Показов 1169. Ответов 19
Метки нет (Все метки)

начал изучать небезопасный код,написал прогу в ней 2 функции одна с управляемым кодом вторая нет,так вот сравнил время выполнения этих функций по секундомеру(программно еще не разобрался как это сделать) в итоге время выполнения каждой из функций заняло примерно 9 секунд.Вопрос в том почему время выполнения небезопасного кода =времени выполнения управляемого и как добиться прироста в скорости?

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Threading;
using System.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Controls;
 
namespace WpfApplication3
{
    class ThreadsClass
    {
        public unsafe string lalala()
        {
            int[] array = new int[230000000];
            fixed (int* aaa = array)
            {
                for (int j = 0; j < 10; j++)
                {
                    for (int i = 0; i < array.Length; i++)
                    {
                        aaa[i] = i;
                    }
                }
            }
            return "END";
        }
 
        public string joj()
        {
            uint[] array = new uint[230000000];
            for (int j = 0; j < 10; j++)
            {
                for (uint i = 0; i < array.Length; i++)
                {
                    array[i] = i;
                }
            }
            return "END";
        }
    }
}
запускаю тут:

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
namespace WpfApplication3
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ThreadsClass ob1 = new ThreadsClass();
            mylabel.Content = ob1.joj(); //ob1.lalala();
        }
    }
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2014, 07:56
Ответы с готовыми решениями:

Запуск неуправляемого кода внутри кода c#
часто требуется при выполнении программы запускать исполняемые файлы (exe) с ключами. Для этого...

Подключение неуправляемого кода
Есть код на С++ struct auth_answer{ int TType; /**&lt; тип транзакции. см...

Вызов неуправляемого кода из длл
Замучался с маршилингом! Есть функция в длл: RetCode = HMM_Path_Init( char *path ); RetCode –...

Как обрабатывать исключения из неуправляемого кода?
Здравствуйте. В приложении используется сторонняя библиотека на c++, в которой периодически...

19
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 08:48 2
Цитата Сообщение от ardos Посмотреть сообщение
Вопрос в том почему время выполнения небезопасного кода =времени выполнения управляемого и как добиться прироста в скорости?
А с чего бы ему отличаться?
0
991 / 889 / 354
Регистрация: 24.03.2014
Сообщений: 2,381
Записей в блоге: 2
19.06.2014, 10:06 3
Цитата Сообщение от ardos Посмотреть сообщение
сравнил время выполнения этих функций по секундомеру
Куранты точнее ж... Или можно ещё 100 на телефоне набрать.

Класс Stopwatch для этого есть...
1
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
19.06.2014, 12:56 4
Лучший ответ Сообщение было отмечено ardos как решение

Решение

Цитата Сообщение от ardos Посмотреть сообщение
почему время выполнения небезопасного кода =времени выполнения управляемого и как добиться прироста в скорости?
Давайте сначала разберемся — почему, собственно, небезопасный и безопасный варианты должны работать с разной скоростью?
В безопасном контексте при доступе к элементам массива рантайм делает проверку на выход индекса за пределы. В цикле на каждой итерации делается дополнительная проверка, что при большом количестве итераций складывается и получается общая просадка по производительности.
При работе с указателями выход за границы массива остается на совести разработчика, потому код должен отрабатывать быстрее... в теории.

На практике же оптимизатор видит, что имеется метод, в котором объявлена локальная переменная, ссылающаяся на массив в цикле от i до длины массива.
Оптимизатору несложно догадаться, что так как переменная локальная, то другой поток ее не изменит, сам массив после создания тоже не меняется, а так как цикл простой for от i до длины, то выхода за границы не может быть в принципе, потому просто не производит проверку на выход на каждой итерации.
В итоге из-за оптимизаций безопасный код отрабатывает так же, как и небезопасный, потому что устраняется главная причина просадки — проверка индекса.
5
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 14:15 5
Цитата Сообщение от kolorotur Посмотреть сообщение
из-за оптимизаций безопасный код отрабатывает так же, как и небезопасный, потому что устраняется главная причина просадки — проверка индекса
как показало уже 2 темы, проверка индекса в безопасном коде, в принципе, не оказывает влияния на скорость.
0
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
19.06.2014, 15:00 6
Цитата Сообщение от pycture Посмотреть сообщение
проверка индекса в безопасном коде, в принципе, не оказывает влияния на скорость.
А что оказывает?
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 15:17 7
Цитата Сообщение от kolorotur Посмотреть сообщение
А что оказывает?
да ниче не оказывает. что safe, что unsafe, одинакого работает
0
1269 / 970 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
19.06.2014, 16:16 8
думаю правильней сказать что unsafe в некоторых случаях позволяет сделать что-то особое, за счет чего и достигается скорость
сам по себе unsafe в вакууме не быстрей safe в том же вакууме
я не поэт конечно, но мысль вы поняли )
0
12 / 12 / 7
Регистрация: 05.06.2012
Сообщений: 280
19.06.2014, 17:22 9
Цитата Сообщение от kolorotur Посмотреть сообщение
На практике же оптимизатор видит, что имеется метод, в котором объявлена локальная переменная, ссылающаяся на массив в цикле от i до длины массива.
Оптимизатору несложно догадаться, что так как переменная локальная, то другой поток ее не изменит, сам массив после создания тоже не меняется, а так как цикл простой for от i до длины, то выхода за границы не может быть в принципе, потому просто не производит проверку на выход на каждой итерации.
ardos, а попробуй в настройках проекта убрать галочку Optimize code.
0
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
19.06.2014, 17:53 10
Лучший ответ Сообщение было отмечено ardos как решение

Решение

Цитата Сообщение от pycture Посмотреть сообщение
что safe, что unsafe, одинакого работает
Так потому и работают одинаково, что оптимизатор при простом обходе эту разницу срезает

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

Немножко причесанный код автора. массив небольшого размера, но обходится часто. Все, что не относится к измеряемому, вынесено из методов:
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
const int iterations = 1000 * 1000 * 10;
 
static unsafe void Main()
{
    // JIT precompile
    int x = 0;
    Unsafe(&x, 1);
    Safe(new int[1], 1);
 
    int size = 1024; 
    int[] array = new int[size];
 
    var sw = new Stopwatch();
    fixed (int* ptr = array)
    {
        sw.Restart();
        Unsafe(ptr, array.Length);
        sw.Stop();
        Console.WriteLine("Unsafe:\t{0}", sw.Elapsed);
    }
 
    sw.Restart();
    Safe(array, array.Length);
    sw.Stop();
    Console.WriteLine("Safe:\t{0}", sw.Elapsed);
 
    Console.ReadLine();
}
  
static unsafe void Unsafe(int* array, int n)
{
    for (int j = 0; j < iterations; j++)
        for (int i = 0; i < n; i++)
            array[i] = i;
}
 
static void Safe(int[] array, int n)
{
    for (int j = 0; j < iterations; j++)
        for (int i = 0; i < n; i++)
            array[i] = i;
}
Запускаем, смотрим:

Unsafe: 00:00:05.3895866
Safe: 00:00:15.5075143

Теперь изменяем метод Safe, чтобы он вместо переменной n в проверке цикла использовал array.Length, тем самым подрубив оптимизатор, который срежет проверки:

Unsafe: 00:00:05.3783892
Safe: 00:00:05.3859151

Вот теперь действительно разницы нет

Что касается многомерных массивов, то, насколько мне известно, при их обходе джиттер никакой оптимизации вообще не проводит, потому небезопасный обход там всегда будет быстрее.
Хотя, в последних версиях рантайма может и запилили оптимизацию.
1
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 19:22 11
Цитата Сообщение от kolorotur Посмотреть сообщение
Запускаем, смотрим
Код
Safe:   00:00:00.7879580
Unsafe: 00:00:00.4319091
Теперь изменяем метод Safe. Просто изменяем
C#
1
2
3
4
5
6
static void Safe(int[] array, int n)
{
    for (int i = 0; i < n; i++)
        for (int j = 0; j < iterations; j++)
                array[i] = i;
}
Запускаем, смотрим
Код
Safe:   00:00:00.3397149
Unsafe: 00:00:00.3347451
Упс. А что поменялось? Ничего, кроме скорости. А проверки при записи в массив, как были так и остались, но на скорость теперь никак не влияют.

Добавлено через 1 минуту
У unsafe скорость подрасла. Он также был переписан
0
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
19.06.2014, 19:40 12
pycture, вы не под отладчиком в debug-билде проверяли? Студийный отладчик по умолчанию отключает JIT-оптимизации.
Мой результат с вашими изменениями:
Unsafe: 00:00:05.7764228
Safe: 00:00:15.4849475

Метод Safe скопирован из вашего сообщения, метод Unsafe не менялся.

Добавлено через 2 минуты
То же самое, но при запуске под студийным отладчиком:
Unsafe: 00:00:31.1890356
Safe: 00:00:36.9089222
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 19:41 13
Цитата Сообщение от kolorotur Посмотреть сообщение
вы не под отладчиком в debug-билде проверяли
оба варианта, в релизе, из-под фара. т.е. влияния студии 0.
.net 4 win 8.1 x64 i5 3230m
0
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
19.06.2014, 22:19 14
Цитата Сообщение от pycture Посмотреть сообщение
.net 4 win 8.1 x64 i5 3230m
Проверял на .NET 4 Win XP SP3 на каком-то древнем AMD.
Доползу до дома — проверю на Win7 x64 i5

Добавлено через 1 час 44 минуты
Как и предполагалось:
Unsafe: 00:00:04.4063939
Safe: 00:00:07.6066734

Это если проект отстроен под x86.
Вот под x64:
Unsafe: 00:00:05.1728827
Safe: 00:00:07.9313476

То же самое, но в методе Safe переменная n заменена на array.Length:
Unsafe: 00:00:03.9905866
Safe: 00:00:03.7868160
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
19.06.2014, 23:10 15
kolorotur, у меня так
Код
Unsafe: 00:00:03.3528329
SafeJI: 00:00:06.8304640
Safe  : 00:00:03.3457161
странно что ваш i5 такой медленный
собсно код http://ideone.com/EGnHrA
и даже тут SafeJI стабильно медленее чем Safe. есть объяснение?
То же самое, но в методе Safe переменная n заменена на array.Length:
Unsafe: 00:00:03.9905866
а здесь что чего скорость поменялась? ведь Unsafe не использует проверку индекса или как?

Добавлено через 6 минут
а еще более странно что у вас код x64 под 64-битной осью работает медленее чем 32-х битная эмуляция в той же 64-х битной оси. всегда наоборот было
0
Эксперт .NET
16342 / 12310 / 3229
Регистрация: 17.09.2011
Сообщений: 20,446
20.06.2014, 00:34 16
Цитата Сообщение от pycture Посмотреть сообщение
странно что ваш i5 такой медленный
i5 2410M @ 2.30GHz, лаптоп.
Судя по коду на ideone, у вас 1000х1000х1 итераций, я проверял на 1000х1000х10, может из-за этого, а может у меня память медленней.

Цитата Сообщение от pycture Посмотреть сообщение
и даже тут SafeJI стабильно медленее чем Safe. есть объяснение?
Предполагаю, что 1024 раза по 1М раз записать в один и тот же адрес быстрее, чем 1М раз в 1024 адреса.
Кэширование инструкций/памяти на уровне ЦП?

Цитата Сообщение от pycture Посмотреть сообщение
Unsafe не использует проверку индекса или как?
Неа, не используют.

Цитата Сообщение от pycture Посмотреть сообщение
а здесь что чего скорость поменялась?
Цитата Сообщение от pycture Посмотреть сообщение
а еще более странно что у вас код x64 под 64-битной осью работает медленее чем 32-х битная эмуляция в той же 64-х битной оси. всегда наоборот было
А черт ее знает.
Как говорится, за что купил...
0
Master of Orion
Эксперт .NET
6091 / 4947 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
20.06.2014, 03:12 17
pycture, что-то у вас не первый раз результаты какие-то особые выходят...
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
20.06.2014, 07:10 18
Цитата Сообщение от kolorotur Посмотреть сообщение
Судя по коду на ideone, у вас 1000х1000х1 итераций, я проверял на 1000х1000х10
Так на ideone ограничение в 5 сек. там больше не успевает. На домашнем с которого результате в 3 сек отрабатывает 1000х1000х10.
Цитата Сообщение от kolorotur Посмотреть сообщение
Предполагаю, что 1024 раза по 1М раз записать в один и тот же адрес быстрее, чем 1М раз в 1024 адреса.
Кэширование инструкций/памяти на уровне ЦП?
Очень маловероятно, 1кБ памяти в кэш любого уровня влазит. Да и кешировании кода в 200 байт тоже в обоих случаях одинаково.
Цитата Сообщение от kolorotur Посмотреть сообщение
i5 2410M
Подозреваю что причина где то тут.
http://www.cpu-world.com/Compa... GA%29.html
Sandy Bridge != Ivy Bridge
Хотя это вопрос о медненности х64 кода на х64 оси в вашем случае не снимает
Цитата Сообщение от Psilon Посмотреть сообщение
что-то у вас не первый раз результаты какие-то особые выходят...
современное ПО, современное железо (даже уже не очень современное), ниче странного не вижу
у вас кстати в данном случае какие результаты?

Добавлено через 2 минуты
что-то у вас не первый раз результаты какие-то особые выходят...
угу. у людей 64-х битный код в 64-ч битной оси работает медленей чем в той же оси 32-х битный а у меня значит результаты особые. ну-ну..
0
Master of Orion
Эксперт .NET
6091 / 4947 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
20.06.2014, 16:04 19
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
        static void Safe(int[] array, int n)
        {
            for (int j = 0; j < iterations; j++)
                for (int i = 0; i < n; i++)
                    array[i] = i;
        }
Unsafe: 00:00:03.6242437
Safe: 00:00:06.7663438

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
        static void Safe(int[] array)
        {
            for (int j = 0; j < iterations; j++)
                for (int i = 0; i < array.Length; i++)
                    array[i] = i;
        }
Unsafe: 00:00:03.6699494
Safe: 00:00:03.7763097

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
        static void Safe(int[] array, int n)
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < iterations; j++)
                    array[i] = i;
        }
Unsafe: 00:00:03.6950082
Safe: 00:00:06.7589647


Добавлено через 28 секунд
i7-3615QM win7x64 anycpu

Добавлено через 1 минуту
Во всех случаях менял только метод Safe. Если есть другие вариации - пишите полный код, чтобы результаты коррелировали...
0
583 / 370 / 63
Регистрация: 22.07.2009
Сообщений: 875
Записей в блоге: 4
21.06.2014, 05:23 20
Поделюсь своим опытом - оптимизация с помощью небезопасного кода 1-мерного массива особого смысла не имеет.
Вот 2х-мерных - имеет.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.06.2014, 05:23
Помогаю со студенческими работами здесь

Безопасность управляемого кода .NET
Прочитал для меня шокирующие заявление в статье журнала argc &amp; argv '...При этом, вам нужно...

Недопустимое сочетание управляемого и неуправляемого типов
Написал на C++ dll-ку: extern &quot;C&quot; __declspec(dllexport) double *mas (double Xmin, double Xmax,...

Взаимодействие управляемого и не управляемого кода
Есть проект Win32Project1 В Win32Project1 есть функция void Test() { MessageBox( 0,...

опасности неуправляемого кода
какие опасности несет в себе неуправляемый код. На ум приходит только назначение переменным...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru