С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 47, средняя оценка - 4.74
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

Что делает данный код и зачем такое кому-нибудь может понадобиться? - C++

08.06.2009, 23:57. Просмотров 6411. Ответов 37
Метки нет (Все метки)

Я ответил на вопрос,но точной формулировки не нашёл,хотел бы свериться(приложения с ответами нет).Задание:
Чёрный ящик.Что делается в данном примере?Зачем кому нибудь может понадобиться подобный код?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void send (int* to,int* from,int count)
{
    int n = (count+7)/8;
    swith(count%8)
    {
           case 0: do { *to++=*from++;
           case 7:        *to++=*from++;
           case 6:        *to++=*from++;
           case 5:        *to++=*from++;
           case 4:        *to++=*from++;
           case 3:        *to++=*from++;
           case 2:        *to++=*from++;
           case 1:        *to++=*from++;
                            }  while(--n>0);
     }
}
Я так думаю,параметр count содержит количество незаполненных байт(или не байт,но кратно 8-ми) "чего-то",и копируется информация(из массива в массив),пока нужное количество элементов не скопируется.Только меня смущает одна штука:если count%8==7,то не рухнет ли вся программа из-за разорванного цикла?Может это ловушка,чтобы программа вылетела?
8
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.06.2009, 23:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Что делает данный код и зачем такое кому-нибудь может понадобиться? (C++):

Кто-нибудь может подробно объяснить, что такое allocators, зачем это и что с ними делать? Нигде не нашёл инфы - C++
Заранее спасибо.

Может кому понадобиться Выключение/перезагрузки компа и завершение сеанса - C++
Копался в windows.h искал чего нибудь интересного вот и нашел.... Вообщем функция для выключения перезагрузки и завершения сеанса...

зачем может понадобиться делать операторы виртуальными? - C++
Дорогие программисты, во первых, хочу поздравить вас с Наступающим новым Годом! Я к вам обращаюсь с маленькой просьбой. Я никак не могу...

Что делает данный код? - C++
#include <iostream> #include <queue> using namespace std; int main() { queue <int> x1; queue <int> x2; queue <int>...

Что делает данный код? - C++
for (int i = 0; i<s1.length(); i++) if (s2.find(s1) != string::npos) cout << s1;

Скажите, что делает данный код? - C++
Решил немного поэкспериментировать и столкнулся с чем-то новым и непонятным для меня. Что делает этот код? Что он выводит и в зависимости...

37
XuTPbIu_MuHTAu
Эксперт С++
2228 / 743 / 10
Регистрация: 27.05.2008
Сообщений: 1,498
09.06.2009, 01:33 #2
Единственное,что я пока смог придумать - уменьшить количество сравнений при копировании. Деление на восемь выполняется быстро,деление на восемь с остатком тоже шустро,а потом имеем то же копирование,но счетчик уменьшается в 8 раз реже.

#pragma,а что значит "разорванный цикл"?) Си - это низкоуровневый ассемблер. Свич тут просто определяет, с какой точки цикл начнется ( причем компилятор тут сделает таблицу джампов,а не кучу сравнений).

Добавлено через 29 минут 46 секунд
Интересно.Буду говорить не называя цифр.
Я взял функцию
Код
void cpy (int * to,int * from,int count) {
    for(int i =0;i<count;i++)
        *to++=*from++;
};
При малых count разницу не замерять особо.Начиная с некоторых cpy ощутимо отстает от send. При средних - отстает неощутимо. При больших cpy работает быстрее.
Не думаю, что у всех результат будет такой.Вообще-то,все должно зависить от механизма предсказания переходов,конвеера и проч. Интересно посмотреть,как выйдет на интеле,у меня атлончик.)

Добавлено через 18 секунд
Интересная темка,спасибо автору ^^
2
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 08:43 #3
pragma, почитай тут, там я уже описывал семантику switch'а Проверьте себя. А хорошо ли вы знакомы со switch'ом?
А задачка и вправду прикольная. Где такое достаёшь? Если в институте, то хороший у вас преподаватель

Добавлено через 1 минуту 0 секунд
Цитата Сообщение от XuTPbIu_MuHTAu Посмотреть сообщение
Единственное,что я пока смог придумать...
Не та том посте на "Спасибо" нажал
1
EnzoMatrix
120 / 120 / 5
Регистрация: 14.03.2009
Сообщений: 462
09.06.2009, 10:41 #4
решил прогнать прогу под досбоксом, результаты поражают для 32000 прогонов при count=20, send работает в 2,5 раза быстрее, тока я так и не понял за счет чего такой прирост в скорости
0
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 10:49 #5
В 2.5 раза быстрее чем что?
0
EnzoMatrix
120 / 120 / 5
Регистрация: 14.03.2009
Сообщений: 462
09.06.2009, 10:53 #6
чем по индексам приравнивать, но если брать эту функцию,
Цитата Сообщение от XuTPbIu_MuHTAu Посмотреть сообщение
Код:
void cpy (int * to,int * from,int count) {
for(int i =0;i<count;i++)
*to++=*from++;
};
то cpy пашет на 25% быстрее чем send
1
Patch
2277 / 492 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
09.06.2009, 11:46 #7
еще бы.
switch - это цепочка if(a == b) goto xx.
в исходном коде таких ветвлений 7.
а ветвление(оно-же - условный переход)... если почитать документацию по процессорам...
при неверном предсказании обрывает суперконвейер, и требует заново загрузить данные из кэша.
что требует очень много времени.
а вот на старых процессорах тот код со switch делался быстрее, чем версия от XuTPbIu_MuHTAu
1
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 12:10 #8
Цитата Сообщение от CartmanRules Посмотреть сообщение
чем по индексам приравнивать, но если брать эту функцию
Всё равно я так и не понял, что сравнивалось с чем и кто круче

Добавлено через 1 минуту 48 секунд
Цитата Сообщение от Patch Посмотреть сообщение
switch - это цепочка if(a == b) goto xx.
По замыслу switch был коммутируемым переходом, а потому любой более-менее приличный компилятор в культурном случае построит switch на ОДНОМ динамическом переходе (правда при этом будет как минимум один статический переход, чтобы проверить, что значение ключа попадает в диапазон case'ов). В итоге код с 1000 алтернативами будет работать так же быстро, как код с 2000 альтернатив
1
EnzoMatrix
120 / 120 / 5
Регистрация: 14.03.2009
Сообщений: 462
09.06.2009, 12:11 #9
Цитата Сообщение от Evg Посмотреть сообщение
Всё равно я так и не понял, что сравнивалось с чем и кто круче
извиняюсь за тупость высказывания*sorry*
сравнивалась send и
C++
1
2
for(i;i<count;i++)
  to[i]=from[i];
send работал в два с половиной раза шустрей это конструкции
0
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 12:13 #10
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от CartmanRules Посмотреть сообщение
извиняюсь за тупость высказывания*sorry*
сравнивалась send и
C++
1
2
for(i;i<count;i++)
  to[i]=from[i];
Принципиальная разница между send'ом и этим кодом в том, что в твоём коде получается на одну итерацию цикла идёт одна пересылка. Т.е. количество операций передачи упарвления (который в данном случае НЕ являются полезными) равно количеству пересылок и, будем условно считать, что занимают 50% времени.

В варианте с send'ом получается, что на 8 пересылок у тебяодин переход и таким образом на НЕполезные операции уходит (опять-таки условно) порядка 10% времени

(to pragma)
Выше и написано, в чём заключается действие этого "чёрного ящика". Т.е. мы делаем некий аналог широкого копирования (которое ты видел в навороченной реализации strcpy), только широта тут заключается в том, что уменьшается доля бесполезных операций перехода. А switch нужен для того, чтобы правильно отпилить начало (т.е. чтобы при копировании 13 байт сначала скопировалось 5, а затем уже шло пачками по 8)
6
EnzoMatrix
120 / 120 / 5
Регистрация: 14.03.2009
Сообщений: 462
09.06.2009, 12:18 #11
т.е. данный код (который с функцией send) можно назвать по стуи развернуутым циклом, если я правильно понял
и еще вопрос в чем такое принципиальное отличие между
C++
1
2
for(i;i<count;i++)
  to[i]=from[i];
и кодом, который привел хитрый_минай?
0
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 12:29 #12
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от CartmanRules Посмотреть сообщение
т.е. данный код (который с функцией send) можно назвать по стуи развернуутым циклом, если я правильно понял
Я не знаю, как правильно по-русски, по-английски называется unrolled loop. По сути да, это раскрученный цикл с хорошим preloop'ом

Цитата Сообщение от CartmanRules Посмотреть сообщение
и еще вопрос в чем такое принципиальное отличие между
Щас положу два кода, чтобы перед глазами было

C
1
2
for(int i =0;i<count;i++)
  *to++=*from++;
C
1
2
for(i;i<count;i++)
  to[i]=from[i];
По принципу работы разницы нет. Но здесь есть разница по скорости работы. Т.е. для первого кода на каждой итерации цикла помимо пересылки, инкрементации i и перехода делается две операции сложения (to++, from++, i++). Во втором случае дооплнительных операций больше: т.е. нужно вычислять адрес to[i], который равен (to + i *sizeof(char)). Т.е. к двум операциям сложения у тебя добавились две операции умножения. В случае с char'ом его размер равен единице, а потому операцию умножения компилятор выкинет. Но вот если копирование будет проходить int'ами, то от умножения уже никуда не деться (хотьи реализовано оно удет через сдвиг, но тем не менее две лишние операции в цикле появятся).

Приличный оптимизирующий компилятор скорее всего сведёт второй код к первому (случай у нас простой), но вот в более сложном случае не факт, что это получится сделать
4
Patch
2277 / 492 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
09.06.2009, 15:13 #13
Цитата Сообщение от Evg Посмотреть сообщение
любой более-менее приличный компилятор в культурном случае построит switch на ОДНОМ динамическом переходе
для сравнений переменной с последовательными значениями - пожалуй.
и даже при этом код примерно вдвое диннее.
для непоследовательных значений - switch строится только на проверках каждого значения.
лучший код такого рода, который я видел делал что-то вроде бинарного дерева...
получалось на 20 значений - 6 условных переходов.
0
Evg
Эксперт CАвтор FAQ
18384 / 6432 / 441
Регистрация: 30.03.2009
Сообщений: 17,855
Записей в блоге: 28
09.06.2009, 15:16 #14
Цитата Сообщение от Patch Посмотреть сообщение
для непоследовательных значений - switch строится только на проверках каждого значения.
Ничего подобного. Либо у тебя в руках был плохой компилятор. В случае непоследовательных значений в таблице переходов на месте "дырок" долен стоять адрес default'а

Цитата Сообщение от Patch Посмотреть сообщение
лучший код такого рода, который я видел делал что-то вроде бинарного дерева...
получалось на 20 значений - 6 условных переходов.
Всё-таки какой компилятор и включены ли опции оптимизации (и какие опции)?
1
Patch
2277 / 492 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
09.06.2009, 15:23 #15
Цитата Сообщение от Evg Посмотреть сообщение
Всё-таки какой компилятор
вот не помню. вскрывал что-то для личных нужд...
а вкрывал я немало. любопытный очень.
0
09.06.2009, 15:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.06.2009, 15:23
Привет! Вот еще темы с ответами:

Обьясните пожайлуста как и что делает данный оператор в этом выражении fState [x][y] ^= 1;. Неполный код привожу ниже. - C++
Вот код программы из книжки Ч. Петзолд (Програмирование для Windows® 95) #define DIVISIONS 5 ... ... LRESULT CALLBACK WndProc(HWND...

Что делает данный цикл ? - C++
ребят что делает данный цикл ? { for (int j=0; j&lt;5; j++) std::cout &lt;&lt;std::setw(3) &lt;&lt;a; std::cout &lt;&lt;'\n';...

Что делает данный цикл? - C++
void startAgain() { int i = 0, j = 0, n = 3; for (i = 0; i &lt; 3; i++) { for (j = 0; j &lt; 3; j++) { fields = n; n++; ...

сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь усложнять? - C++
сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.