Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Накладные расходы unsafe


Автор: Kronos 26.6.2005, 11:04
Где то (сейчас уже не припомню где) наткнулся на утверждение, что использование unsafe блоков связано с накладными расходами при переходе в такой блок и выходе из него.

Потом специально искал подробности об этом но так и не нашел. Может их этих расходов нет вообще?

Потому спрашиваю здесь. Если есть спецы, которые знают подробности поясните. Есть ли такие накладные расходы. Откуда берутся. В первую очередь интересует падение производительности. Как классический пример, насколько плохо переходить в unsafe и выходить оттуда много раз подряд в цикле.

Автор: Domestic Cat 26.6.2005, 23:40
По идее да, если ансейф блок ничего не делает, то его вызов будет немного менее выгодным.

Код

class Test
{
        delegate void Method(); 
        Method[] methods;

        Test()
        {
            methods = new Method[] {new Method(UnsafeMethod), new Method(SafeMethod)};
        }
        
        void DoTest()
        {
            foreach (Method m in methods)
            {
                long before = DateTime.Now.Ticks;
                for (int i = 0; i < 20000000; i++) m();
                long after = DateTime.Now.Ticks;
                Console.WriteLine("Method " + m.Method.Name + " takes " + new TimeSpan(after - before));
            }
        }

        unsafe void UnsafeMethod()
        {
            int i = 100;
        }

        void SafeMethod()
        {
            int i = 100;
        }



        static void Main(string[] args)
        {
            Test test = new Test();
            test.DoTest();
        }
        
    }

Если же ансейф что-то делает, до он будет быстрее.

Автор: Kronos 27.6.2005, 06:45
Цитата(Domestic @ 26.6.2005, 20:40)
По идее да, если ансейф блок ничего не делает, то его вызов будет немного менее выгодным.


Код

Цитата(Domestic @ 26.6.2005, 20:40)
Если же ансейф что-то делает, до он будет быстрее.


Попробовал я такой код. Меняя несколько варианты содержимого функций и их вызов уже из контекста unsafe блока и из обычного контекста.

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

Автор: Domestic Cat 27.6.2005, 06:53
Цитата(Kronos @ 26.6.2005, 21:45)
У меня странные результаты. Во первых затраченное время меняется незначительно (даже если в функции добавить еще несколько арифметических опреаций. Во вторых в одних сборках чуть быстрее unsafe, в других safe. Вообще закономерностей не заметил. Есть еще предположение о работе оптимизатора, который портит нам логику работы (или нет?).

Ну да, по идее компилятор или JIT может вообще выбросить пустые методы или инлайнить код. Хотя у меня вроде этого не делалось, т.к. стабильно ансейф был немного медленнее.

Автор: Guest 27.6.2005, 08:52
Цитата(Domestic @ 27.6.2005, 06:53)
Ну да, по идее компилятор или JIT может вообще выбросить пустые методы или инлайнить код. Хотя у меня вроде этого не делалось, т.к. стабильно ансейф был немного медленнее.


Я компилировал из командной строки. csc t.txt /unsafe
Уж не знаю что там по умолчанию. Чтобы исключить затраты на компиляцию во время исполнения добавил еще один вызов DoTest();.

Кроме того попробовал сам DoTest объявить unsafe и (или) вызывать DoTest так.

unsafe
{ test.DoTest();
}

Всегда время было 0.375 или 0.39... (точно не помню). От случая к случаю эти два числа вроде случайно менялись. Возможно затраты на вызов функции просто так велики, что содержимое простых функций вообще практически незаметно и safe или unsafe тоже. Короче надо исследовать этот вопрос. Попробую еще варианты.

Автор: Kronos 28.6.2005, 20:21
В обще вроде никаких значимых расходов на переход в unsafe нет. Для простейших функций разница в нескольког процентов времени исполнения. Варьируется от сборки к сборке. Причем явных закономерностей, что будет быстрее не выявлено. Часто второй проход по идентичному циклу занимает даже чуть большее время, что тоже странно.

Но меня терзают смутные сомнения. Если в функции, объявленной как unsafe, не используется никаких возможностей unsafe, то вдруг компилятор просто удаляет такие блоки unsafe и трактует их как обычные?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)