Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.03.2012, 00:28   #1
zrs
Новичок
Джуниор
 
Регистрация: 19.03.2012
Сообщений: 1
По умолчанию Быстродействие вычислительных операций C#, С++

Всем здравствуйте.

Есть тройной цикл, выполняющий некие вычисления:

//расчет автокорреляционных функций
double a1 = 0;

kor = new double[nrow / 4 + 1, 201];
for (int k = 0; k < 201; k++)
{
for (int j = 0; j <= nrow / 4; j++)
{
for (int i = 0; i < (nrow - j); i++)
{
a1 = a1 + ((pole[i, k] - mo[k]) * (pole[i + j, k] - mo[k]));
}
//A = a1 / (nrow);
kor[j, k] = a1 / nrow;
a1 = 0;
}
}

Размерность матрицы большая, и работает этот цикл долго. Этот код был переписан с с++.
На с++ для размерности матрицы 5000х200 (считывается из файла) этот цикл выполняется около 15 секунд, а на c# 2.5 минуты.

Скажите пожалуйста, почему?!) И как сделать так, чтобы на шарпе он выполнялся также как на си?
zrs вне форума Ответить с цитированием
Старый 19.03.2012, 08:15   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

шарп это dotNET, а dotNET это виртуальная машина.
пусть JIT и отрабатывает свое, но VM делает больше проверок нежели С++.
отсюда и понижение скорости.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 19.03.2012, 09:47   #3
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Во-первых, дотнет проверяет, чтобы a+b не было больше int.MaxValue, иначе выбрасывает OverflowException. Избежать лишних проверок можно так:
Код:
unchecked
{
	с = a + b;
	// прочий код без проверки переполнения
}
Такая программа будет вести себя как в C++.
Upd: выяснил, что по умолчанию проверка переполнения отключена.

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

Код:
using System;
using System.Runtime.InteropServices;

class Program
{
	static unsafe void Main ()
	{
		const int lenght = 100;
		int *a = (int*)Marshal.AllocHGlobal (lenght * sizeof (int)).ToPointer ();
		for (int i = 0; i < lenght; i++)
			a[i] = i;
		Marshal.FreeHGlobal (new IntPtr (a));
	}
}
В свойствах проекта нужно будет указать Allow unsafe code.

В-третьих, jitter может и не сообразить, что выражения типа (nrow - j) не изменяются с каждой итерацией. Сохранение результата во временной переменной может дать небольшой прирост скорости.


Я советую обрамить этот участок кода в Stopwatch Start и Stop, и выяснить, даёт ли каждый из этих способов реальный прирост производительности. Иначе это будет излишнее усложнение кода.

P. S. Дополнительное ускорение даст многопоточность. Плюс для конченых извращенцев самый хардкорный вариант: добавить в солюшн проект C++ со вставками на ассемблере, и этот код уже вызывать из C#.

Последний раз редактировалось ds.Dante; 19.03.2012 в 10:16.
ds.Dante вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Быстродействие VBA Sasha_Smirnov Microsoft Office Word 24 06.12.2012 13:35
Создание программы по выполнению вычислительных операций над матрицами andrew_1 Помощь студентам 5 19.11.2011 17:09
Быстродействие SQL и C# Manolla C# (си шарп) 3 28.09.2011 08:26
Быстродействие инструментов С++ coinkrsk Общие вопросы C/C++ 2 07.10.2010 13:34
Быстродействие sxerox Паскаль, Turbo Pascal, PascalABC.NET 2 19.04.2010 18:53