Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
tvy
Зарегистрирован: 26.09.2005 Сообщения: 1
|
Добавлено: Пн Сен 26 2005 14:37 Заголовок сообщения: Нужна максимальная скорость программы |
|
|
Нужна максимальная скорость программы (сложение, сравнение целочисленных переменных, в том числе лежащих в Byte массивах, циклы FOR и DO и пр. похожие операции). В начале и в конце программы есть чтение из файлов и визуальное отображение.
На каком языке какой версии это лучше делать? |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Пн Сен 26 2005 14:47 Заголовок сообщения: |
|
|
Мда... Не мешало бы по конкретнее осветить проблему.Что конкретно надо сделать сколько есть времени на выполнение на какой платформе и пр. Еще, не гонитесь за низкоуровневой оптимизацией, толку от нее......
Вообще есть много способов сделать программу быстрее. Если уж впадать в крайности, то берем ассемблер, используем MMX и прочие расширения, обращаем внимание как процессор предсказывает переходы, для этого нужно знать точную модель процессора, не забываем о схеме кэширования и следим чтоб все конвейеры были максимально загружены. |
|
Вернуться к началу |
|
|
Dimasm
Зарегистрирован: 25.04.2005 Сообщения: 454
|
Добавлено: Пн Сен 26 2005 20:02 Заголовок сообщения: |
|
|
Если в двух словах...
1. писать на чём хорошо умеешь, но не на скриптовых языках, лучше что-то в стиле С++ плюс ассембленые вставки.
2. оптимизированный алгоритм. Только за счёт подбора и оптимизации алгоритма можно получить от 20 до 500% прироста в скорости
например
Код: | float *result = new float [100];
for( int i = 0;i<100;i++)
{
result[i] = 0.22*sin(13)*i*i;
} |
вот так будет быстрее
Код: | float *result = new float [100];
float A = 0.22*sin(13);
for( int i = 0;i<100;i++)
{
result[i] = A*i*i;
} |
кстати i*i это быстрее чем pow(i,2) (для С++)
есть "высокоуровневая оптимизация"-оптимизация на уровне алгоритма есть "низкоуровневая оптимизация" - на уровне программы.
Рекомендуют сосредотачиваться на первом типе.
3. если представить, что в предыдущем примере нужно выполнить немного циклов, 20 например, то лучше не полениться и записать так
Код: | float *result = new float [20];
float A = 0.22*sin(13);
result[0] = 0;
result[1] = A;
result[2] = A*4;
result[3] = A*9;
....
будет быстрее выполняться
|
4. если переменная меняется от 1-го до 100, то лучше юзать не Integer а Byte (для С++)
5. стараться не работать со строками, если это возможно.
лучше всего компьютер работает с числами, желательно целыми, а ещё круче с логичекими переменными false-true, 0-1 так что если можно свести алгоритм к этому, хотябы частично, то это большой плюс
6. когда напишите алгоритм, замеряете сколько времени выполняется каждая его стадия, и оптимизируете то, что работает очень долго, либо что-то меняете в алгоритме,либо вставками на ассемблере.
7. если файлы не большие, то это не будет причиной "заторов"
а вот визуализация.... вот она может вам всё очень подпортить, хотя смотря что и как вы будете визуализировать
недавно делал программу для решения сисем линейных уравнений. загоняю систему из 3-х уравнений - время рассчёта от 1 до 3 мс, думаю, а если загнать систему из 300 уравнений? сделал из 255, больше Excel не позволил. Загнал, жду минуту, две, 10... понял что не дождусь. поменял int на byte, inline функции и.т.д - ничего не меняется
замеряю какая операция алгоритма занимает больше всего времени, оказалось что это парсинг строки(программа уравнение читает из текстового файла, потом выделяет коэффициенты, потом считает)
То есть разбор пары сотен строк выполнялся в 200 тыс раз медленнее чем обсчёт массива с 65 тысячами переменных типа Extended по которым раз 10 пробегали циклом и выполняли всякие математические преобразования.
Поменял алгоритм парсинга и:
до
1. чтени файла 3 мс
2. парсинг уравнения ~10 мин
3. рассчёт(собственно алгоритм)3 мс
после
1. чтени файла 3 мс
2. парсинг уравнения ~30 сек (можно и быстрее но меня это устроило)
3. рассчёт 3 мс
это я к тому, что сперва надо "ловить" узкие места а потом "ускорять" их.
8. смотря для какого компа пишите. если это алгоритм загружает комп на 40 процентов, то можно разделить его пополам и пустить на два потока, думаю как минимум в 1.8 раза будет быстрее. Если используете многопроцессорную платформу - там ещё одно "поле" для "разгона"
9. если вы "вылизали" алгоритм, и уже нет возможности его оптимизировать, тогда, как говорил Kefir юзаем MMX SSE 3DNow....
10. если вы, говоря о "версии" языка имели в виду компилятор, то думаю, что это будет играть второстепенную роль. Естетвенно, лучше использовать более новые. |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Пн Сен 26 2005 21:26 Заголовок сообщения: |
|
|
Цитата: | 4. если переменная меняется от 1-го до 100, то лучше юзать не Integer а Byte (для С++) |
Ой ли? У меня shortы по сравнению с intами заметно тормозили.
Цитата: | лучше всего компьютер работает с числами, желательно целыми, а ещё круче с логичекими переменными false-true |
Если в сях, то там bool - фактически псевдоним intа. |
|
Вернуться к началу |
|
|
Dimasm
Зарегистрирован: 25.04.2005 Сообщения: 454
|
Добавлено: Пн Сен 26 2005 22:11 Заголовок сообщения: |
|
|
Wladimir писал(а): | Цитата: | 4. если переменная меняется от 1-го до 100, то лучше юзать не Integer а Byte (для С++) |
Ой ли? У меня shortы по сравнению с intами заметно тормозили.
|
с Byte в С++ я погоречился, это наследство Delphi для Builder
если юзать char, __int8 - они памяти занимают в двое меньше чем int или short int. Логично предположить что и работа с ними будет шустрее
Wladimir писал(а): |
Цитата: | лучше всего компьютер работает с числами, желательно целыми, а ещё круче с логичекими переменными false-true |
Если в сях, то там bool - фактически псевдоним intа. |
Это далеко не аналоги.
для хранения переменной int, нужно 16 бит
10, это в битах 00000000001010 (примерно)
а bool в битах это 0 или 1
переменная bool занимает 1 бит - в 16 раз меньше чем int!
просто в С++ есть возможность задавать значение этой переменной
как bool value = 1 (false) или
int d = 0;
bool ff=d;
int и bool это не аналоги |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вт Сен 27 2005 11:41 Заголовок сообщения: |
|
|
По пункту 4 ускорения от использования char не будет, наоборот если уж оптимизировать алгоритм, то лучше всего использовать тип int. Он хоть и больше но арифметические операции в целочисленными переменными как правило компиляторами выполняются в int. Т.е. сперав из char делается int затем производится арифметическая операция, затем обратно. Единственным оправдванием использования char является то что он мало места занимает, т.е. требуется меньшая пропускная спосбность различных каналов. Но, как подсказывает мой опыт и нехитрые подсчеты, моя очень слабенькая шина памяти не является узким местом выполнения численных алгоритмов. Логические переменные в Си это как раз инты и работа с ними идет как с интами. Но есть хороший пример в книге Зубкова "Ассемблер для Дос, виндовс и Юникс". Там рассказывается про чемпионат по написанию программы жизнь. Самая бытрая версия обрабатывала сразу по 16 ячеек, т.к. состояние каждой ячейки хранилось в одном бите слова. Т.е. если надо обрабатывать большие объемы булевых переменных можно ускорить процесс разместив их в одну переменную. Про компиляторы: слышал я на днях что программы компилированные Интелами работают иногда в 3 раза быстрее чем микрософт. |
|
Вернуться к началу |
|
|
Dimasm
Зарегистрирован: 25.04.2005 Сообщения: 454
|
Добавлено: Вт Сен 27 2005 12:17 Заголовок сообщения: |
|
|
Kefir писал(а): | По пункту 4 ускорения от использования char не будет, наоборот если уж оптимизировать алгоритм, то лучше всего использовать тип int. Он хоть и больше но арифметические операции в целочисленными переменными как правило компиляторами выполняются в int. Т.е. сперав из char делается int затем производится арифметическая операция, затем обратно. |
будем знать
Kefir писал(а): |
Логические переменные в Си это как раз инты и работа с ними идет как с интами.
|
ну не знаю, выходит что int - forever
Kefir писал(а): | Но есть хороший пример в книге Зубкова "Ассемблер для Дос, виндовс и Юникс". Там рассказывается про чемпионат по написанию программы жизнь. Самая бытрая версия обрабатывала сразу по 16 ячеек, т.к. состояние каждой ячейки хранилось в одном бите слова. Т.е. если надо обрабатывать большие объемы булевых переменных можно ускорить процесс разместив их в одну переменную. |
Прикольно, как раз такая на полке стоит. надо почитать
это типа так:
Код: |
void Fun1(int value)
{
// оптимизированная функция, которая работает
// с int переменной как массивом
// bool[15] - 0110101111101010
asm{
...
};
}
// массив который надо быстро обрабатывать
bool * m = new bool [1024];
for( int i = 0 ; i < 1024 ; i=i+16 )
{
Fun1(m[i]>>m[i+1]....m[i+15]);
//эта строчка будет как-то по другому
// написал просто для примера
}
|
Kefir писал(а): | Про компиляторы: слышал я на днях что программы компилированные Интелами работают иногда в 3 раза быстрее чем микрософт. |
ну так они наверняка компилируются с оптимизацией под свои процы.
у меня где-то встречался интеловский компилятор, так с ним кажется прога шла по тестированию проги и оптимизации.
ведь даже когда указать при компиляции ядра линухи MMX а не стандартнок i386, то тот же код будет компилироваться с оптимизацией под MMX и соответственно выполняться быстрее. А кто кроме интел лучше всего знает свои процессоры, да и не только свои
ещё я слышал, что можно переменную "принудительно" поместить в регистры процессора
register int value; - как-то так.
но эффекта что-то не заметил
вообще я сторонник глубокого "вылизывания" алгоритма остальное второстепенно. |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вт Сен 27 2005 12:50 Заголовок сообщения: |
|
|
Ключевое слово register, по моему, есть даже в стандарте ANSI C, но это всего лишь рекомендация компилятору. И насколько я опнимаю большинство компиляторов его не воспринимают вовсе, особенно те которые на x86, там ведь регистров мало очень... Современные компиляторы сами знают когда поместить переменную в регистр и нет необходимости им это указывать явно, можно покапаться в настройках компилятора. Там есть много опций, ну например встраивание функции в код, то есть не вызов а встраивание. Вспоминается мне одна беседа в ФИДО там чел долго и отважно оптимизировал свой компилятор, не помню уже какой, под одну прогу, его после спросили: а на ассемблере написать не проще было? |
|
Вернуться к началу |
|
|
Dimasm
Зарегистрирован: 25.04.2005 Сообщения: 454
|
Добавлено: Вт Сен 27 2005 13:12 Заголовок сообщения: |
|
|
ассемблер такая штука, для многих трудно-понимаемая.
это как линукс после винды, надо ломать своё мировоззрение.
мне, вероятно, былобы проще подобрать ключи и диррективы компилятору, чем реализовывать это на асме.
Я понимаю если ты начал кодить контроллеры на асме, потом изучил С++, то для тебя регистры, счётчики ... - это родное.
А если начал с бейсика, и не уходил в сторону от языков выского уровня? я так и не смог вникнут в асм хотя наверное небыло стоящей мотивации. а любопытно то как
Kefir писал(а): | Но есть хороший пример в книге Зубкова "Ассемблер для Дос, виндовс и Юникс". Там рассказывается про чемпионат по написанию программы жизнь. |
чё то я не нашёл, раздел хотябы можешь подсказать? |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Вт Сен 27 2005 20:46 Заголовок сообщения: |
|
|
Цитата: | ну не знаю, выходит что int - forever |
int - не просто forever.
Это вообще - Единственный Тип Данных. По крайней мере, с точки зрения процессора.
В BCPL, кажется, именно так и было.
Про Жизнь в Зубкове - точно было. Там даже рекорд приводится: жизнь размером в 59 байт.[/quote] |
|
Вернуться к началу |
|
|
|