Скорость выполнения программы
Это на чем такое заключение основанно?
А во вторых, есть данные собственных наблюдений: имеется программа математических расчетов, которая запускалась на процессоре Pentium 1800 и AMD 3500+ и что то я не заметил, чтоб на втором проце она быстрее работала (операционка везде XP). Зато если запускать на Pentium 3000, то будет видно увеличение скорости выполнения. Правда точно скорость выполнения я не измерял... все оценки проводились "на глаз" :)
А во вторых, есть данные собственных наблюдений: имеется программа математических расчетов, которая запускалась на процессоре Pentium 1800 и AMD 3500+ и что то я не заметил, чтоб на втором проце она быстрее работала (операционка везде XP). Зато если запускать на Pentium 3000, то будет видно увеличение скорости выполнения. Правда точно скорость выполнения я не измерял... все оценки проводились "на глаз" :)
Замерь точно результаты, хотя бы стандартными функциями, и покажи.
И потом, если тесты выполнялись на разных машинах, то там не было в это время включено разных служб тормозящих?
e-XperT, а вы не могли бы поделиться исходником программы, вычисляющей интеграл методом Монте-Карло ? а то написал прогу, работает, но не правильно...а по-другому сделать не могу((
Не уверен, что это поможет)
спасибо, а почему вы думаете что не поможет ?) Мне то нужно написать консольную программу, которая считает интеграл 1 - x*x на интервале [-1;1] ..
согласен, посмотрел программу - написана на высоком уровне, для меня это слишком круто. Создал тему, посмотрите пожалуйста) http://forum.codenet.ru/showthread.php?p=312894#post312894
Да уж, твой код ужасен.
Рекомендую почитать что-нибудь по стилистике кода. В т.ч. о том, как и где объявлять переменные, как пользоваться классами, как разбивать код, а не делать спагетти.
Рекомендую действительно писать на C++.
Рекомендую пытаться не писать код, который выполняет одни и те же бессмысленные действия.
После чего можно говорить о производительности.
Как можно говорить об оценках производительности процессоров, если у тебя такое в цикле (!!!):
{
fout.open("C:\\TensionDistribution\\Field.txt",ios::app);
......
fout.close();
fout.open("C:\\TensionDistribution\\FullEnergy.txt",ios::app);
......
fout.close();
fout.open("C:\\TensionDistribution\\TensionDistribution.txt",ios::app);
......
fout.close();
}
Тебе переменных жалко? :)
Кроме того, вывод в файл, по сравнению с основным циклом расчета по методу Монте-Карло, занимает просто доли процента. Так что объявление нескольких переменных вместо одного не приведет к росту производительности.
Сделано это для того, чтобы можно было посмотреть файлы во время выполнения программы. Объявив по переменной для каждого файла и открыв файл прочесть его блокнотом невозможно, поскольку он заблокирован.
А кроме блокнота в мире нет инструментов для просмотра текстовых файлов? ;)
А поскольку программа выполняется несколько недель полезно посмотреть что она там насчитала и прервать расчет, если какой то параметр задан неверно (может быть недостаточно точек для расчета).
М-дя... интересный метод анализа расчетов выполняющихся несколько недель.
Кстати, ты уверен, что они просто обязаны выполняться несколько недель?
Может, за эти несколько недель сделать программу оптимальнее по скорости и посчитать всё за несколько часов?
Можно открывать файл, но для этого проще использовать одну переменную.
Боже... какая милая чушь...
Кому удобнее? Компьютеру? Программисту? Или тому, кто читает твой код?
Да никому из них не удобнее.
А вот бесполезная операция открытия-закрытия файла, инициализации потока - это "отличное дополнение" к методу Монте-Карло.
Кроме того, вывод в файл, по сравнению с основным циклом расчета по методу Монте-Карло, занимает просто доли процента. Так что объявление нескольких переменных вместо одного не приведет к росту производительности.
Откуда такие выкладки? Профайл в студию!
Или это метод научного тыка в действии?
Операции ввода-вывода являются наиболее медленными операциями в системе, а уж в совокупности с созданием системных объектов (открытием файлов) - это вообще корень зла.
Если уж тебя беспокоит производительность, подходи к ней с профессиональной позиции, начинай изучать способы её измерения, нахождения тонких мест и методы оптимизации.
Поэтому я ещё раз предлагаю тебе:
1) привести программу к структурированному и читабельному виду (гоночные автомобили собранные из старых табуреток шурупами, скотчем, ржавыми гвоздями, перетянутые бечевкой, не приходят к финишу первыми), что называется рефакторингом;
2) выбросить явно бесполезные действия;
3) профилировать программу и найти действительно тонкие места;
4) найти способы оптимизации этих мест;
5) повторить с п.1
Ну а для выполнения этого алгоритма надо бы начать учиться писать и доводить до ума программы.
Программа - это сама по себе продукт, а не только результаты её работы.
Некачественный продукт будет давать некачественный результат.
P.S. Приведи код в порядок и попробуем ускорить его (в разы).
P.P.S. Вот это, кстати, тоже "шедевр":
//---------------------------------MC first approach-----------------------------------------
<skip>
//--------------------------energy massive liqiud----------------------------------------------------------------------
<skip>
//---------------------------------------------------------------------------------------------------------------------
for(int j = 0;j<NumExpPt;j++) {
//-------------------Расчет одночастичного потенциала в первом приближении------------------------
<skip>
//------------------расчет эквимолекулярной поверхности в первом приближении----------------------------------------
<skip>
//----------------------------расчет полной энергии объекта--------------------------------------------------
<skip>
Ты что-нибудь о функциях, методах в языке C++ слышал?
Почему бы не применить? Или макароны милее сердцу?
После такого "шедевра", наличие следующего даже не удивило:
Radius = MinR;
//-----------------------density of second approach-------------------------------------------------------------------
RoVap = RoLiq*exp((ELiqInf-EVapInf)/Temperature/2.);
for(int j = 0;j<NumExpPt;j++){
for(int k = 0;k<DataII[j].GetMaxNum();k++) DataII[j].SetDensity(k,RoLiq*exp((ELiqInf-DataI[j].GetField(k))/Temperature/2.));
}
//----------------------------------MC second approach-----------------------------------------------------------------
double rc;
int DenPt;
double DenKoeff;
for(i = 0;i<NumMCTest;i++) {
rp = experiment.RelPoint.Module();
Radius = MinR;
for(int j = 0;j<NumExpPt;j++) {
for(int k = 0;k<DataII[j].GetMaxNum();k++) {
TempPoint = DataII[j].GetIP(k) + experiment.RelPoint;
<skip>
как думаете, что будет в третьем приближении?
Ну конечно:
Radius = MinR;
//-----------------------density of third approach-------------------------------------------------------------------
RoVap = RoLiq*exp((ELiqInfII-EVapInfII)/Temperature/2.);
for(j = 0;j<NumExpPt;j++){
for(int k = 0;k<DataIII[j].GetMaxNum();k++) DataIII[j].SetDensity(k, RoLiq*exp((ELiqInfII-DataII[j].GetField(k))/Temperature/2.));
}
//----------------------------------MC third approach-----------------------------------------------------------------
for(i = 0;i<NumMCTest;i++) {
Radius = MinR;
rp = experiment.RelPoint.Module();
for(int j = 0;j<NumExpPt;j++) {
for(int k = 0;k<DataIII[j].GetMaxNum();k++) {
TempPoint = DataIII[j].GetIP(k) + experiment.RelPoint;
déjà vu
А догадываетесь, как выглядит первое приближение? :)
А зачем извращаться?
М-дя... интересный метод анализа расчетов выполняющихся несколько недель.
Есть какие то другие варианты?
Кстати, ты уверен, что они просто обязаны выполняться несколько недель? Может, за эти несколько недель сделать программу оптимальнее по скорости и посчитать всё за несколько часов?
Откуда такие выкладки? Профайл в студию!
Или это метод научного тыка в действии?
Операции ввода-вывода являются наиболее медленными операциями в системе, а уж в совокупности с созданием системных объектов (открытием файлов) - это вообще корень зла.
Все тормозится при расчете парного потенциала ParPotenc(rp);
Просвети, если знаешь способ быстро просчитать потенциал Леннард-Джонса 4.0/pow(rp,12)-4.0/pow(rp,6) не менее 50000000000 раз.
Если использовать потенциал прямоугольной ямы
if(0<=rp&&rp<ap) return 0.0;
if(rp>=ap) return 1.0;
то программа считает три дня.
Боже... какая милая чушь...
Кому удобнее? Компьютеру? Программисту? Или тому, кто читает твой код?
Программисту. Зачем мне писать такой код
file1.Open("файл1");
...
file1.close();
file2.open("файл2");
...
file2.close();
Если можно это сделать с одной переменной
file.Open("файл1");
...
file.close();
file.open("файл2");
...
file.close();
Думаю второй код более понятен тем, что переменная file используется для работы с выводом в файл.
Если уж тебя беспокоит производительность, подходи к ней с профессиональной позиции, начинай изучать способы её измерения, нахождения тонких мест и методы оптимизации.
Код в программе оптимизирован. Не думаю, что есть какие то другие способы ускорить работу программы. На асме тоже пытался.
P.P.S. Вот это, кстати, тоже "шедевр":
//---------------------------------MC first approach-----------------------------------------
<skip>
//--------------------------energy massive liqiud----------------------------------------------------------------------
<skip>
//---------------------------------------------------------------------------------------------------------------------
for(int j = 0;j<NumExpPt;j++) {
//-------------------Расчет одночастичного потенциала в первом приближении------------------------
<skip>
//------------------расчет эквимолекулярной поверхности в первом приближении----------------------------------------
<skip>
//----------------------------расчет полной энергии объекта--------------------------------------------------
<skip>
Ты что-нибудь о функциях, методах в языке C++ слышал?
Почему бы не применить? Или макароны милее сердцу?
Ты еще предложи по разным модулям растолкать. Программа не настолько большая, чтобы нужно было функции писать. Да и написание функций требует определенного геморроя, поскольку в них нужно еще параметры передавать. Либо все массивы объявлять глобальными, что тоже не есть гуд.
После такого "шедевра", наличие следующего даже не удивило:
Radius = MinR;
//-----------------------density of second approach-------------------------------------------------------------------
RoVap = RoLiq*exp((ELiqInf-EVapInf)/Temperature/2.);
for(int j = 0;j<NumExpPt;j++){
for(int k = 0;k<DataII[j].GetMaxNum();k++) DataII[j].SetDensity(k,RoLiq*exp((ELiqInf-DataI[j].GetField(k))/Temperature/2.));
}
//----------------------------------MC second approach-----------------------------------------------------------------
double rc;
int DenPt;
double DenKoeff;
for(i = 0;i<NumMCTest;i++) {
rp = experiment.RelPoint.Module();
Radius = MinR;
for(int j = 0;j<NumExpPt;j++) {
for(int k = 0;k<DataII[j].GetMaxNum();k++) {
TempPoint = DataII[j].GetIP(k) + experiment.RelPoint;
<skip>
как думаете, что будет в третьем приближении?
Ну конечно:
Radius = MinR;
//-----------------------density of third approach-------------------------------------------------------------------
RoVap = RoLiq*exp((ELiqInfII-EVapInfII)/Temperature/2.);
for(j = 0;j<NumExpPt;j++){
for(int k = 0;k<DataIII[j].GetMaxNum();k++) DataIII[j].SetDensity(k, RoLiq*exp((ELiqInfII-DataII[j].GetField(k))/Temperature/2.));
}
//----------------------------------MC third approach-----------------------------------------------------------------
for(i = 0;i<NumMCTest;i++) {
Radius = MinR;
rp = experiment.RelPoint.Module();
for(int j = 0;j<NumExpPt;j++) {
for(int k = 0;k<DataIII[j].GetMaxNum();k++) {
TempPoint = DataIII[j].GetIP(k) + experiment.RelPoint;
déjà vu
А догадываетесь, как выглядит первое приближение? :)
А вот первое приближение выглядит то по другому, так что первое приближение под шаблон никак не переделать. Что касается второго и третьего, то тут историческая причина почему я шаблон не стал делать. Первоначально предполагалось сделать два приближения. Когда выяснилось что необходимо третье приближение все было уже написано и проще было скопипастить, чем писать шаблон.
Настоятельно рекомендую вам послушать таки комюнити, взять профайлер и попрофайлить. Уверен что пользы от етого будет очень много и ето куда быстрее чем доказывать чтото Green-у или ждать ответа про процесоры.
[COLOR=Silver]
Тем более всеровно не докажете по трем причинам. а) он упрямый, б) он прав, в) если он не прав то вы етого не заметите. :D[/COLOR]
Про рефакторинг (причесывание кода) - ето с одной стороны процесс противоположный оптимизации, но ето только на первый взгляд. Разворачивать методы в инлайн должен компилятор а не девелопер.
Да и без нормального структурирования кода рефакторинг дело малоефективное. Ведь узкое место нужно сначала локализировать чтоб найти. Кроме того со своего скромного опыта скажу что зачастую плуг находится в том месте где вы наименьше его ожидаете.
Ничем помочь топипакастеру не могу, посветовать нечего...
Ну может если только записать программу в одну строчку? :)
P.S. действительно уж "под шаблон не переделать" :D
Код в программе оптимизирован. Не думаю, что есть какие то другие способы ускорить работу программы. На асме тоже пытался.
Когда-то давно, я тоже уперся рогом, что моя программка (C & asm) - верх оптимальности. Я её вылизывал насколько дней, и заставить её выполнять расчеты менее, чем за 6 часов, невозможно. Когда мне показали чудо на C# написанное минут за 30 на коленке, и выполняющее объём вычислений раза в полтора-два больше, и за (внимание) меньше 40 секунд, я испытал чудовищный дискомфорт в области межушного ганглия.
Просвети, если знаешь способ быстро просчитать потенциал Леннард-Джонса 4.0/pow(rp,12)-4.0/pow(rp,6) не менее 50000000000 раз.
Знаю...
но ты же считаешь, что этот код оптимален... :D
Кроме того, зачем забивать тебе голову, такими глупостями, как точность, кеширование и динамическое программирование?
Да и надо закрыть глаза на ошибки в этом куске кода:
if((TmpRF = RectRadFunc(rp)) == 0) continue;
Ладно, давайте потихоньку помогать топикавтору. А то тут и с профайлером можно убиться. Все же были молодые и амбитные.
Вопросы к розмышлению.
1. Что такое pow(rp,12) ?
2. Как щитается pow(rp,12) ?
3. Как щитается pow(rp,6) ?
4. Во сколько раз pow(rp,6) пощитается бистре чем pow(rp,12) ?
5. Как выразить a^(2*b) через a^(b) ?
Для общего развития
Как щитается експонента от Х ?
Как оптимально возвести число в степень 1024 ?
ЗЫ e-XperT, не сочтите что я думаю будто вы не знаете ответов. Просто иногда мы не замечаем простого :)
ЗЫЫ. Не доверяйте оптимизацыю кода компилятору. ХЗ кто его писал :D
Когда мне показали чудо на C# написанное минут за 30 на коленке, и выполняющее объём вычислений раза в полтора-два больше, и за (внимание) меньше 40 секунд
На C# не пробовал, поскольку не слышал, чтобы он быстро выполнял математические вычисления. Обычно все говорят, что на С программы выполняются быстрее.
И где в этом коде ошибка?
if((TmpRF = RectRadFunc(rp)) == 0) continue;
Кроме того, зачем забивать тебе голову, такими глупостями, как точность, кеширование и динамическое программирование
Функция потенциала вызывается с разными значениями, что там можно кэшировать?
Как оптимально возвести число в степень 1024 ?
Использовал бинарный алгоритм умножения
{
double z1 = x*x*x;
double z3 = z1*z1;
return 4.0/z3/z3-4.0/z3;
}
Удалось ускорить в 2.8 раз. Спасибо.
ЗЫЫ. Не доверяйте оптимизацыю кода компилятору. ХЗ кто его писал
Известно кто. Microsoft)
Удалось ускорить в 2.8 раз.
Вот видите :). Вам же просто стараются обяснить, что вы неправильно оптимизацыей занимаетесь. Если правильно реализовать росчеты, то скорость хоть на РНР бедут выше чем на С++ с оптимизацыей компилятором, или на том же Сшарп с его заточкой под процессоры разные.
А вы в позу становитесь. Так что прислушайтесь. Прорефакторите код нормально, чтоб его могли с удовольствием читать не только вы. Сразу все виднее станет и вам в том числе.
Мне собственно и так все видно. Я сам указал на узкое место в программе, поскольку не знал как оптимизировать расчет степенной функции. Даже ускорив программу в 3 раза вывод в файл все равно занимает гораздо меньше времени, чем остальные расчеты. В программе имеется еще выдача на экран _tprintf(_T("\ni = %d"),i);
это осталось с отладки. Расчеты, которые проводились 2 недели выполнялись без этого куска кода.
Я вообще не спрашивал про оптимизацию кода. Вопрос был про скорость выполнения на разных компьютерах. Как было отвечено
И потом, если тесты выполнялись на разных машинах, то там не было в это время включено разных служб тормозящих?
Я сравнил, там действительно были службы, которые влияли на скорость расчета. Когда я сделал все одинаковым результаты стали ожидаемыми.
PS: А что это за профайлер такой?
PS: А что это за профайлер такой?
А вот ознакомьтесь (очевидная ссылка, не правда-ли?).
Меня огорчает ваше представление о размерах "действительно больших проектов" :(
Это для научных расчетов
Я спрашивал про профайлер, а не про профилирование и ожидал получить названия программ или алгоритм составления профайла, который у меня просили.
Откуда такие выкладки? Профайл в студию!
Т.е. список, приведенный в конце этой статьи не устроил? Или просто не дочитал?
К примеру VTune.
upd: к VS тоже нечто подобное прилагается, но такое, блин... неудобное... ИМХО!!!
Код, оставшийся после взрыва на макаронной фабрике, трудно и оптимизировать, и править.
И где в этом коде ошибка?
if((TmpRF = RectRadFunc(rp)) == 0) continue;
Ну а подумать?
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
Зачем его править?
Ну а подумать?
Просмотрел статью. В моем случае все работает правильно, поскольку никаких математических вычислений не производится и функции возвращают 0
)
{
if(0<=rp&&rp<ap) return INFINITY;
if(ap<=rp&&rp<=1.436*ap) return epsilon;
if(rp>1.436*ap) return 0;
return -1;
}
double RectRadFunc(const double &rp //расстояние между взаимодействующими молекулами
)
{
if(0<=rp&&rp<ap) return 0.0;
if(rp>=ap) return 1.0;
return -1;
}
Ошибка накапливается при длительных вычислениях. Даже если присвоить переменной 0,3, что отображается 0.29999999999999999 то сравнивание с 0,3 будет успешным.
Ах да... я же забыл, что этот код идеален по всем параметрам.
Просмотрел статью. В моем случае все работает правильно, поскольку никаких математических вычислений не производится и функции возвращают 0
А это уже не считается мат. вычислениями?
...
if(TmpDen == 0) continue;