2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 10:48 
Аватара пользователя


30/03/10
51
Ткнулся ради интереса в саму библиотеку System::Math:: (тут как в с++ всё же он родней мне :wink: )
вот что испробовал:
код: [ скачать ] [ спрятать ]
Используется синтаксис C#
            // расчёт exp(x)
            {
            System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
            swatch.Start(); // старт
            double z;
            z = 5.0;
            z = System.Math.Exp(z);
            swatch.Stop(); // стоп
            textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
            // раскладываем в ряд
            {
                System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
                swatch.Start(); // старт
                double z;
                z = 5.0;
                z = 1+z+z*z/2+z*z*z/6+z*z*z*z/24+z*z*z*z*z/120 + z*z*z*z*z*z / 720 + z*z*z*z*z*z*z/5040+z*z*z*z*z*z*z*z/40320+ z * z * z * z * z * z * z * z*z/362880;
                swatch.Stop(); // стоп
                textBox1.Text = textBox1.Text + "dz = " + System.Convert.ToString(z-System.Math.Exp(5)) + "\r\n";
                textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
 


Код:
00:00:00.0000076
dz = -4.72370253291172
00:00:00.0000007

- вот что для exp(x), 0.0000076 сек - для родной библиотеки(Math) и сам разложил в ряд Тейлора до n=9
- dz = -4.72370253291172 погрешность между разложением моим и библиотекой(Math)
- для разложения 0.0000007 сек для n=9 при этом x = 5.0;
итого в 10,8571 раза быстрей, думаю, что в самой тут фишка в точности т.к сама среда берёт точность до размерности хранимого типа данных, а именно до double.....
логично, что для всех других стандартных функций такая же история....
думаю в этой стороне посмотрю, пока что - и посмотрим на сколько выйдет увеличить скорость расчёта - но уже что то выпало)

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 12:52 
Аватара пользователя


30/03/10
51
код: [ скачать ] [ спрятать ]
Используется синтаксис C#
 // расчёт логарифма
            {
                System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
                swatch.Start(); // старт
                double z;
                z = 5.0;
                z = System.Math.Log(z);
                swatch.Stop(); // стоп
                textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
            // раскладываем в ряд
            {
                System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
                swatch.Start(); // старт
                double z;
                z = 5.0;
                z = (z - 1.0) / (z + 1.0);
                z = 2.0 * z * (1.0+1.0/3*z*z+1.0/5*z*z*z*z+1.0/7*z*z*z*z*z*z+1.0/9*z*z*z*z*z*z*z*z+1.0/11*z*z*z*z*z*z*z*z*z*z+1.0/13*z*z*z*z*z*z*z*z*z*z*z*z);              
                swatch.Stop(); // стоп
                textBox1.Text = textBox1.Text + "dz = " + System.Convert.ToString(z - System.Math.Log(5.0)) + "\r\n";
                textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
 

то же самое по логарифму с основанием "e" ну вы поняли)
Код:
00:00:00.0000069
dz = -0.000503617533912815
00:00:00.0000007

с отклонением в 0.000503617533912815 для x = 5.0, выходит прирост скорости в 4.9286 раза.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 13:06 
Заслуженный участник


27/04/09
28128
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]

О боги.
1. Вы неправильно измеряете время. Как минимум надо объединить много однотипных повторений интересующего куска в цикле, чтобы уменьшить влияние хоть части шума. Но и это всё равно сгодится только как первое приближение.
2. Не нужно создавать два Stopwatch, хватит и одного.
3. В общем случае для разных значений два способа вычислить одну и ту же числовую функцию могут расходиться друг с другом и относительно точного значения как угодно. По значениям в лишь одном аргументе делать выводы не стоит.
4. Вычисления делает не среда CLR, а скомпилированные из промежуточного языка инструкции для FPU. Методы Math — просто обёртки. (Ну, должно быть так. MS открыли недавно код, и стоит поглядеть, что там…) А уж FPU работает внутри себя с числами разрядности даже больше чем у double. После вычислений они округляются до double/float по надобности.
5. Даже если по результатам измерений и выйдет гарантированное ускорение у менее точно вычисляющего кода, эта погрешность может сказаться на результатах неожиданно сильно. Или ожиданно, но в это не верится. Вы даже так и не сказали, зачем вам такая куча экспонент. А то вдруг надо вычислить, скажем, $e^a, e^{2a},\ldots, e^{na}$ — тут можно делать гораздо меньше $n$ вызовов exp при сохранении неплохой точности.
6. В любом случае голоса в голове говорят «профайлер, профайлер». Я им не пользовался, но все утверждают, что перед оптимизацией скорости стоит сначала узнать, что именно больше всего тормозит — ах, эти странные люди!
7. Используйте String.Format (а когда сложений строк ещё больше, то StringBuilder). Как минимум выглядит яснее:

Используется синтаксис C#
// было
textBox1.Text = textBox1.Text + "dz = " + System.Convert.ToString(z - System.Math.Log(5.0)) + "\r\n";
textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";

// стало
// + в самом начале файла 'using System;', если нету
textBox1.Text += string.Format("dz = {0}\n{1}\n", z - Math.Log(5.0), swatch.Elapsed);

Сейчас вам ещё поквалифицированнее напишут, но столько ляпов в одном месте — надо как-то повнимательнее, что ли… :-)

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 14:33 
Аватара пользователя


30/03/10
51
arseniiv в сообщении #1069507 писал(а):
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]

О боги.
1. Вы неправильно измеряете время. Как минимум надо объединить много однотипных повторений интересующего куска в цикле, чтобы уменьшить влияние хоть части шума. Но и это всё равно сгодится только как первое приближение.
2. Не нужно создавать два Stopwatch, хватит и одного.
3. В общем случае для разных значений два способа вычислить одну и ту же числовую функцию могут расходиться друг с другом и относительно точного значения как угодно. По значениям в лишь одном аргументе делать выводы не стоит.
4. Вычисления делает не среда CLR, а скомпилированные из промежуточного языка инструкции для FPU. Методы Math — просто обёртки. (Ну, должно быть так. MS открыли недавно код, и стоит поглядеть, что там…) А уж FPU работает внутри себя с числами разрядности даже больше чем у double. После вычислений они округляются до double/float по надобности.
5. Даже если по результатам измерений и выйдет гарантированное ускорение у менее точно вычисляющего кода, эта погрешность может сказаться на результатах неожиданно сильно. Или ожиданно, но в это не верится. Вы даже так и не сказали, зачем вам такая куча экспонент. А то вдруг надо вычислить, скажем, $e^a, e^{2a},\ldots, e^{na}$ — тут можно делать гораздо меньше $n$ вызовов exp при сохранении неплохой точности.
6. В любом случае голоса в голове говорят «профайлер, профайлер». Я им не пользовался, но все утверждают, что перед оптимизацией скорости стоит сначала узнать, что именно больше всего тормозит — ах, эти странные люди!
7. Используйте String.Format (а когда сложений строк ещё больше, то StringBuilder). Как минимум выглядит яснее:

Используется синтаксис C#
// было
textBox1.Text = textBox1.Text + "dz = " + System.Convert.ToString(z - System.Math.Log(5.0)) + "\r\n";
textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";

// стало
// + в самом начале файла 'using System;', если нету
textBox1.Text += string.Format("dz = {0}\n{1}\n", z - Math.Log(5.0), swatch.Elapsed);

Сейчас вам ещё поквалифицированнее напишут, но столько ляпов в одном месте — надо как-то повнимательнее, что ли… :-)


- да я понимаю Вас :D вы же понимаете, что я специально вывел два сегмента в отдельные части.
- ну про строчку:
Используется синтаксис C#
// стало
// + в самом начале файла 'using System;', если нету
textBox1.Text += string.Format("dz = {0}\n{1}\n", z - Math.Log(5.0), swatch.Elapsed);

это понятно, она вынесена за пределы stop_time - так что форма неважна, ну да согласен с Вами - грамотность программная :oops: :roll:
- ну по поводу измерения, да согласен - очень трудно - т.к запустил, что то левое и получил другое время; поэтому расчёт идёт сразу друг за другом два модуля;

-- Пн ноя 02, 2015 15:39:23 --

код: [ скачать ] [ спрятать ]
Используется синтаксис C#
            // ----------------------------------------------
            // - ------ тестовый расчёт ---------------------
            {
                System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
                swatch.Start(); // старт
                double p1, p2, p3, p4, p5, p6, p7;
                p1 = 10.0;
                p2 = 8.0;
                p3 = 7.0;
                p4 = 6.0;
                p5 = 5.0;
                p6 = 4.0;
                p7 = 3.0;
                double q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13;
                int z;
                double R;
                double T;
                T = 500.0;
                R = 478.0;
                z = 15;
                q1 = System.Math.Sqrt((p1 * p1 - p2 * p2) / (z * R * T));
                q2 = System.Math.Sqrt((p2 * p2 - p3 * p3) / (z * R * T));
                q3 = System.Math.Sqrt((p3 * p3 - p4 * p4) / (z * R * T));
                q4 = System.Math.Sqrt((p4 * p4 - p5 * p5) / (z * R * T));
                q5 = System.Math.Sqrt((p5 * p5 - p6 * p6) / (z * R * T));
                q6 = System.Math.Sqrt((p6 * p6 - p7 * p7) / (z * R * T));
                q7 = System.Math.Sqrt((p1 * p1 - p3 * p3) / (z * R * T));
                q8 = System.Math.Sqrt((p1 * p1 - p4 * p4) / (z * R * T));
                q9 = System.Math.Sqrt((p1 * p1 - p5 * p5) / (z * R * T));
                q10 = System.Math.Sqrt((p1 * p1 - p6 * p6) / (z * R * T));
                double ro;
                ro = p1 / R / T;
                q11 = ro*System.Math.Exp((1/1.8)*System.Math.Log(p2/p1))*System.Math.Sqrt(2*1.8/(0.8)*p1/ro*(1-System.Math.Exp((0.8/1.8)*System.Math.Log(p2/p1))));
                q12 = ro * System.Math.Exp((1 / 1.8) * System.Math.Log(p3 / p1)) * System.Math.Sqrt(2 * 1.8 / (0.8) * p1 / ro * (1 - System.Math.Exp((0.8 / 1.8) * System.Math.Log(p3 / p1))));
                q13 = ro * System.Math.Exp((1 / 1.8) * System.Math.Log(p4 / p1)) * System.Math.Sqrt(2 * 1.8 / (0.8) * p1 / ro * (1 - System.Math.Exp((0.8 / 1.8) * System.Math.Log(p4 / p1))));
                swatch.Stop(); // стоп
                textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
            // ----------------------------------------------
            // ------ теперь через разложения ---------------
            {
                System.Diagnostics.Stopwatch swatch = new System.Diagnostics.Stopwatch();// создаем объект
                swatch.Start(); // старт
                double p1, p2, p3, p4, p5, p6, p7;
                p1 = 10.0;
                p2 = 8.0;
                p3 = 7.0;
                p4 = 6.0;
                p5 = 5.0;
                p6 = 4.0;
                p7 = 3.0;
                double q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, q13;
                int z;
                double R;
                double T;
                T = 500.0;
                R = 478.0;
                z = 15;
                double ro;
                ro = p1 / R / T;
                double x, y;
                x = 0.0;
                y = 0.0;
                //q1 = System.Math.Sqrt((p1 * p1 - p2 * p2) / (z * R * T));
                x = (p1 * p1 - p2 * p2) / z / R / T;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.5 * x;
                q1 = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
               
                //q2 = System.Math.Sqrt((p2 * p2 - p3 * p3) / (z * R * T));
                x = (p2 * p2 - p3 * p3) / z / R / T;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);

                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                //q8 = System.Math.Sqrt((p1 * p1 - p4 * p4) / (z * R * T));
                x = (p1 * p1 - p4 * p4) / z / R / T;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.5 * x;
                q8 = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                //q9 = System.Math.Sqrt((p1 * p1 - p5 * p5) / (z * R * T));
                x = (p1 * p1 - p5 * p5) / z / R / T;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.5 * x;
                q9 = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                //q10 = System.Math.Sqrt((p1 * p1 - p6 * p6) / (z * R * T));
                x = (p1 * p1 - p6 * p6) / z / R / T;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.5 * x;
                q10 = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                //q11 = ro * System.Math.Exp((1 / 1.8) * System.Math.Log(p2 / p1)) * System.Math.Sqrt(2 * 1.8 / (0.8) * p1 / ro * (1 - System.Math.Exp((0.8 / 1.8) * System.Math.Log(p2 / p1))));
                x = p2/p1*1.0;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8/1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = p1 / ro * 1.0*2*1.8/0.8;
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8 / 1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = x * ro;
                y = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                y = y * 1 / 1.8;
                y = 1.0 + y + y * y / 2.0 + y * y * y / 6.0 + y * y * y * y / 24.0 +
                    y * y * y * y * y / 120.0 + y * y * y * y * y * y / 720.0 +
                    y * y * y * y * y * y * y / 5040.0 + y * y * y * y * y * y * y * y / 40320.0 +
                    y * y * y * y * y * y * y * y * y / 362880.0 + y * y * y * y * y * y * y * y * y * y / 3628800.0;
                q11 = x * y * 1.0;
                //q12 = ro * System.Math.Exp((1 / 1.8) * System.Math.Log(p3 / p1)) * System.Math.Sqrt(2 * 1.8 / (0.8) * p1 / ro * (1 - System.Math.Exp((0.8 / 1.8) * System.Math.Log(p3 / p1))));
                x = p3 / p1 * 1.0;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8 / 1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = p1 / ro * 1.0 * 2 * 1.8 / 0.8;
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8 / 1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = x * ro;
                y = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                y = y * 1 / 1.8;
                y = 1.0 + y + y * y / 2.0 + y * y * y / 6.0 + y * y * y * y / 24.0 +
                    y * y * y * y * y / 120.0 + y * y * y * y * y * y / 720.0 +
                    y * y * y * y * y * y * y / 5040.0 + y * y * y * y * y * y * y * y / 40320.0 +
                    y * y * y * y * y * y * y * y * y / 362880.0 + y * y * y * y * y * y * y * y * y * y / 3628800.0;
                q12 = x * y * 1.0;
                //q13 = ro * System.Math.Exp((1 / 1.8) * System.Math.Log(p4 / p1)) * System.Math.Sqrt(2 * 1.8 / (0.8) * p1 / ro * (1 - System.Math.Exp((0.8 / 1.8) * System.Math.Log(p4 / p1))));
                x = p4 / p1 * 1.0;
                y = (x - 1.0) / (x + 1.0);
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8 / 1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = p1 / ro * 1.0 * 2 * 1.8 / 0.8;
                x = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                x = 0.8 / 1.8 * x;
                x = 1.0 + x + x * x / 2.0 + x * x * x / 6.0 + x * x * x * x / 24.0 +
                    x * x * x * x * x / 120.0 + x * x * x * x * x * x / 720.0 +
                    x * x * x * x * x * x * x / 5040.0 + x * x * x * x * x * x * x * x / 40320.0 +
                    x * x * x * x * x * x * x * x * x / 362880.0 + x * x * x * x * x * x * x * x * x * x / 3628800.0;
                x = x * ro;
                y = 2 * y * (1 + 1 / 3.0 * y * y + 1 / 5.0 * y * y * y * y + 1 / 7.0 * y * y * y * y * y * y + 1 / 9.0 * y * y * y * y * y * y * y * y + 1 / 11.0 * y * y * y * y * y * y * y * y * y * y
                    + 1 / 13.0 * y * y * y * y * y * y * y * y * y * y * y * y + 1 / 15.0 * y * y * y * y * y * y * y * y * y * y * y * y * y * y);
                y = y * 1 / 1.8;
                y = 1.0 + y + y * y / 2.0 + y * y * y / 6.0 + y * y * y * y / 24.0 +
                    y * y * y * y * y / 120.0 + y * y * y * y * y * y / 720.0 +
                    y * y * y * y * y * y * y / 5040.0 + y * y * y * y * y * y * y * y / 40320.0 +
                    y * y * y * y * y * y * y * y * y / 362880.0 + y * y * y * y * y * y * y * y * y * y / 3628800.0;
                q13 = x * y * 1.0;

                swatch.Stop(); // стоп
                textBox1.Text = textBox1.Text + System.Convert.ToString(swatch.Elapsed) + "\r\n";
            }
            // ----------------------------------------------
 

- короче половину выпилил, по времени пошло плоховато: 40% спасает по скорости.... по поводу погрешности 10 степень разложения, обеспечивает требуемую погрешность в 0,1-0,3%

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 14:51 
Заслуженный участник


20/08/14
11780
Россия, Москва
Ну и при разложении неплохо бы использовать что-то аналогичное "схеме Горнера" (вычисление следующей производной из предыдущей, а не с самого начала), хотя это может и компилятор соптимизировать ...
В качестве dz выводите относительную погрешность, а не абсолютную, последняя собственно почти ни о чём не говорит.
И не забудьте что double даёт точность практически 16 знаков, т.е. относительную погрешность около $10^{-16}$. Ну или хоть float с его точностью 7 знаков (или $10^{-7}$). Вот когда получите близкую точность с разложением в ряд - тогда и сравнивайте скорости. А то точность логарифма в 0.03% и экспоненты в 3% (!!) ну совершенно не впечатляет, несмотря даже на скорость.
Для точности в 3% достаточно таблички из сотни значений, которая "вычисляться" будет ещё во много раз быстрее.
Ну и как правильно указали, замеряйте время вычислений хотя бы сотни миллионов итераций (чтобы общее время составило десятки секунд и более).

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 14:53 
Аватара пользователя


30/03/10
51
arseniiv в сообщении #1069507 писал(а):
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]
1. Вы неправильно измеряете время. Как минимум надо объединить много однотипных повторений интересующего куска в цикле, чтобы уменьшить влияние хоть части шума. Но и это всё равно сгодится только как первое приближение.

- тут я ответил ранним Вам постом....
arseniiv в сообщении #1069507 писал(а):
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]
Не нужно создавать два Stopwatch, хватит и одного.

ну да согласен :oops: - просто тут я скоро пихну их в потоки для определения времени расчёта, так заготовка..
arseniiv в сообщении #1069507 писал(а):
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]
4. Вычисления делает не среда CLR, а скомпилированные из промежуточного языка инструкции для FPU. Методы Math — просто обёртки. (Ну, должно быть так. MS открыли недавно код, и стоит поглядеть, что там…) А уж FPU работает внутри себя с числами разрядности даже больше чем у double. После вычислений они округляются до double/float по надобности.

- посмотрел и был удивлён :D - действительно скажем так в этой библиотеке они болт ложили на скорость :facepalm:
arseniiv в сообщении #1069507 писал(а):
[В ответ на экспоненту, хотя к коду для логарифма это тоже относится.]
В любом случае голоса в голове говорят «профайлер, профайлер». Я им не пользовался, но все утверждают, что перед оптимизацией скорости стоит сначала узнать, что именно больше всего тормозит — ах, эти странные люди!

и тут вы правы, как раз две операции Ln(x) Exp(x) а именно
Код:
Exp(()*Ln())

- думаю понятно, что тут можно вертеть степень.... вот тут съедается удивительно много времени, а как думаете почему?
- как я понял из описания, т.к юзают товарищи приближённые методы - а именно через аппроксимацию находят, пока погрешность не станет 0,000000- и т.д = ) а уровень думаете какой, если по pi считать то 3.14159265358979323846

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 14:58 
Заслуженный участник


20/08/14
11780
Россия, Москва
gdoom в сообщении #1069536 писал(а):
обеспечивает требуемую погрешность в 0,1-0,3%
Кошмар, для получения такой точности достаточно операций с целыми числами 16 битов длиной (или даже меньше), точнее дробными, но размером 16 бит в сумме, все функции сделайте табличными, ну и компилятору разрешить (и заставить) использовать SSE/AVX (т.к. много параллельных операций).

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 15:00 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
gdoom в сообщении #1069541 писал(а):
- посмотрел и был удивлён :D - действительно скажем так в этой библиотеке они болт ложили на скорость
Код покажите, как вы это меряли, а то есть у меня подозрение одно...

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение02.11.2015, 17:14 
Заслуженный участник


27/04/09
28128
gdoom в сообщении #1069541 писал(а):
и тут вы правы, как раз две операции Ln(x) Exp(x)
Как раз-таки много всяких операций, в том числе в полном коде (про который, в основном, и речь: вы сейчас пытаетесь оптимизировать что-то ещё и в пику точности, когда, возможно, есть оптимизация другого, и без таких жертв) ещё и возня с потоками.

Вы так и не сказали, зачем такая куча экспонент. Логика подсказывает, что именно её надо попытаться оптимизировать в первую очередь.

-- Пн ноя 02, 2015 19:16:48 --

arseniiv в сообщении #1069507 писал(а):
MS открыли недавно код, и стоит поглядеть, что там…
(Для заинтересованных.) Ага, там все интересные методы у Math помечены как автогенерируемые: http://referencesource.microsoft.com/#mscorlib/system/math.cs. Может быть, они инлайниться даже могут благодаря этому…

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение03.11.2015, 06:14 
Аватара пользователя


30/03/10
51
Dmitriy40 в сообщении #1069543 писал(а):
gdoom в сообщении #1069536 писал(а):
обеспечивает требуемую погрешность в 0,1-0,3%
Кошмар, для получения такой точности достаточно операций с целыми числами 16 битов длиной (или даже меньше), точнее дробными, но размером 16 бит в сумме, все функции сделайте табличными, ну и компилятору разрешить (и заставить) использовать SSE/AVX (т.к. много параллельных операций).

- а вот это вариант, попробую, спасибо большое)
rockclimber в сообщении #1069544 писал(а):
gdoom в сообщении #1069541 писал(а):
- посмотрел и был удивлён :D - действительно скажем так в этой библиотеке они болт ложили на скорость
Код покажите, как вы это меряли, а то есть у меня подозрение одно...

код выше валяется, хотя тут я не согласен с методом оценки времени - конечно, для меня проще замеры - как для микроконтрольщика :D есть код на asm - е где я могу посмотреть количество тактов и умножить на время выполнения такта)
arseniiv в сообщении #1069507 писал(а):
MS открыли недавно код, и стоит поглядеть, что там…
(Для заинтересованных.) Ага, там все интересные методы у Math помечены как автогенерируемые: http://referencesource.microsoft.com/#mscorlib/system/math.cs. Может быть, они инлайниться даже могут благодаря этому…[/quote]
- не увидел к сожалению вставок, может ткнёте меня непосредственно в кусок кода пожалуйста :oops:
а вот как я вижу алгоритм быстрый http://www.azillionmonkeys.com/qed/sqroot.html

-- Вт ноя 03, 2015 07:30:11 --

По поводу вопроса, что за задача - уравнения, что применяются - это уравнения расхода через лабиринтное уплотнение, вот немного пояснение http://www.findpatent.ru/patent/238/2382893.html - в ГТД двигателе такими уплотнениями регулируются система охлаждения внутренних узлов двигателя, а так же регулируется равномерно распределения усилия на узлы ротора. Их расчёт очень большая проблема на сегодня и как только не извращаются, для вычисления - в советское время просто заменяли на аналог электрической цепи. Система течения - это гидравлическая схема(только вот там сжимаемая среда). Участки регулировки представляют из себя - систему дроссель участков, трубок и отверстий.
http://uploads.ru/0c4ld.png

-- Вт ноя 03, 2015 07:34:25 --

на картинке слева - идёт камера сгорания, потом сопловой аппарат, после идёт 3ступени турбины. Стрелками отмечаются направления течения.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение03.11.2015, 06:56 


11/12/14
893
gdoom в сообщении #1069742 писал(а):
как для микроконтрольщика :D есть код на asm - е где я могу посмотреть количество тактов и умножить на время выполнения такта)


У меня для вас плохие новости - на современных процессорах уже десятки лет этот подход просто не работает.

Базовые азы современных реалий:
- Процессор - это сложная нелинейная система параллельных вычислителей, только притворяющаяся былой машиной состояний с линейными переходами от команды к команде. "скорость инструкции" замерить просто нельзя. Правдоподобно меряются только огромные (читай - очень огромные) блоки инструкций.
- Львиный вклад в производительность современного процессора осуществляет кеширование обмена данными с ОЗУ. Кеш. Это и проблема для правдоподобных замеров, потому что, к примеру, суммируя два огромных массива вы сразу же рискуете померять не скорость процессора, а скорость шины памяти, процессор будет просто простаивать ожидая ввода-вывода, т.к. суммировать он умеет параллельно с этими собственно пересылками, очень очень долгими в мерках процессорных тактов. Кроме того первая итерация цикла интенсивных вычислений "локальных" может исполнятся гораздо дольше последующих, т.к. в ней заполняется кеш. В общем с кешем надо быть тоже очень аккуратным. И в то же время очень важно иметь это ввиду так как переписывание кода в, как говорят, кеш-френдли форму может привести к десятикратным ростам производительности.
- Не забывать про многозадачность ОС, если в момент промера у вас кванты времени "удачно" улетели в другие процессы - получится тоже чушь.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение03.11.2015, 10:40 
Заслуженный участник


27/04/09
28128
gdoom в сообщении #1069742 писал(а):
не увидел к сожалению вставок, может ткнёте меня непосредственно в кусок кода пожалуйста :oops:
Я и говорю, определений в этом исходном коде нет. Надо в другом месте искать, в коде, компилирующемся не в IL, вероятно, написанном на C++. Лень смотреть, раскрыт он там у них или нет. Ничего кроме тривиальной обёртки над инструкцией FEXP там быть не может.

-- Вт ноя 03, 2015 12:43:19 --

(Оффтоп)

gdoom в сообщении #1069742 писал(а):
По поводу вопроса, что за задача - уравнения, что применяются - это уравнения расхода через лабиринтное уплотнение, вот немного пояснение http://www.findpatent.ru/patent/238/2382893.html
- в ГТД двигателе такими уплотнениями регулируются система охлаждения внутренних узлов двигателя, а так же регулируется равномерно распределения усилия на узлы ротора. Их расчёт очень большая проблема на сегодня и как только не извращаются, для вычисления - в советское время просто заменяли на аналог электрической цепи. Система течения - это гидравлическая схема(только вот там сжимаемая среда). Участки регулировки представляют из себя - систему дроссель участков, трубок и отверстий.
http://uploads.ru/0c4ld.png
Ну, если не хотите говорить, откуда именно экспоненты именно в таком количестве, как хотите. С самого начала это перевыводить вряд ли многие захотят.

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение03.11.2015, 12:04 
Аватара пользователя


30/03/10
51
aa_dav в сообщении #1069743 писал(а):
gdoom в сообщении #1069742 писал(а):
как для микроконтрольщика :D есть код на asm - е где я могу посмотреть количество тактов и умножить на время выполнения такта)


У меня для вас плохие новости - на современных процессорах уже десятки лет этот подход просто не работает.

Базовые азы современных реалий:
- Процессор - это сложная нелинейная система параллельных вычислителей, только притворяющаяся былой машиной состояний с линейными переходами от команды к команде. "скорость инструкции" замерить просто нельзя. Правдоподобно меряются только огромные (читай - очень огромные) блоки инструкций.
- Львиный вклад в производительность современного процессора осуществляет кеширование обмена данными с ОЗУ. Кеш. Это и проблема для правдоподобных замеров, потому что, к примеру, суммируя два огромных массива вы сразу же рискуете померять не скорость процессора, а скорость шины памяти, процессор будет просто простаивать ожидая ввода-вывода, т.к. суммировать он умеет параллельно с этими собственно пересылками, очень очень долгими в мерках процессорных тактов. Кроме того первая итерация цикла интенсивных вычислений "локальных" может исполнятся гораздо дольше последующих, т.к. в ней заполняется кеш. В общем с кешем надо быть тоже очень аккуратным. И в то же время очень важно иметь это ввиду так как переписывание кода в, как говорят, кеш-френдли форму может привести к десятикратным ростам производительности.
- Не забывать про многозадачность ОС, если в момент промера у вас кванты времени "удачно" улетели в другие процессы - получится тоже чушь.


- я поэтому и говорю, что в микроконтроллерах со временем проще определиться - а вот с осью нужно всё отключить по возможности и выполнить N раз операцию загрузки и получить распределение статистическое по времени. :roll: я это понимаю хорошо, ну ладно завтра праздник, как раз будет время уже накидать и немного отполировать код и там посмотрю, что дальше)

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение11.11.2015, 13:40 
Аватара пользователя


30/03/10
51
Добрый день друзья, давно не выходил - много работы :facepalm:.
Ну как стало понятно по ходу разработки и изучению статей:
http://habrahabr.ru/post/111021/
а так же капания в алгоритмах, стало ясно что очень хорошо жрёт ресурс:
Log() - просто ужасно есть ресурсы, как видно после изучения http://maths-people.anu.edu.au/~brent/pd/RNC7t.pdf вот этой интересной публикации понятно стало, что Log в Math модуле находиться через дискретные приближения, т.к они решают проблемы в общем - то есть, аргумент функции логарифма может быть рациональным числом(понятно что >1) и принимать значения гораздо больше единицы. Вот тут и проблема, что для отрезков [1,10] разложение в ряд Тейлора канает, а вот потом всё медленней сходиться при этом очень. Дискретный метод хорош, тем что похож на метод ньютона - но там проблемы с схождением для больших величин, но сходиться n^2 быстрей для "x" до 9000000, а вот дальше опять проблемы. Для величин "x" от 9000 очень рулит Fast Algorithms for High-Precision Computation of Elementary Functions Richard P. Brent метод этих ребят :shock: . Так что с логарифмом получилось справиться, пока точных цифр не могу сказать - ещё пилю алгоритм.
Далее проще с функцией квадратного корня - там метод ньютона рулит до величин 9000000.0 за 14 итераций всё (10^-5) погрешность это пойдёт для моих вычислений. Ах да Log теперь считается за 6 итераций :roll: и при этом этого метода нет в Math модуле C#(я же говорил что болт положили они 8-) ) (32 стр - в брашуре, что указал).
И пока ещё не решил проблему с Exp - но опять же буду пилить из брашуры, что указал(обратите внимание на год 2006! - и на вики там ссылка на не ёж, работа при этом совсем свежая - как я понял).
Вот пока, что так получается. Соберу алгоритм уже скоро посмотрим сколько по производительности будет)

-- Ср ноя 11, 2015 14:50:57 --

Ах да по поводу вычислений ISO/IEC 9899:1999 согласно ему - требования по ошибке должны бить в размере формата исчисления то есть если double (15 знаков)так, что и тут накладные на вычисления - а модуль расчёта С# соответственно удовлетворяют требованиям ISO вот тут и ноги растут на их длительность)

 Профиль  
                  
 
 Re: visual studio 200X многопоточность С#
Сообщение11.11.2015, 14:40 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Там в заметке упоминается, что автор пишет книгу по этой теме. Книга вышла в 2010, скачать ее можно тут: http://www.loria.fr/~zimmerma/mca/mca-cup-0.5.9.pdf

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group