Главное меню
Мы солидарны с Украиной. Узнайте здесь, как можно поддержать Украину.

Что за чушь (g++)

Автор Алексей Гринь, июля 8, 2009, 11:12

0 Пользователи и 1 гость просматривают эту тему.

Алексей Гринь

Кто-нибудь, объясните.

Есть у меня цикл. Думаю, как бы его заставить быстрее работать.
Вижу, что в одной из функции есть такая строка
if(!key)
                throw NullException(1);

По логике она там не шибко нужна (вызывающая функция уже проверила объект на нуль), я её удаляю (цикл у меня большой и любое действие, вплоть до простого приравнивания к нулю, имеет большие последствия).
И самый прикол, что после удаления мой цикл стал отрабатывать ещё медленнее (!) на 40 мс. Возвращую строку на место - цикл снова ускоряется ровно на 40 мс. При чём с тем же сталкивался я при обнулении объектов (там вплоть до 200 мс). Если их обнулять, то скорость без внятных причин поднимается, хотя
1) обнуление это лишний запись в память
2) логически оно мне это не надо.

Ничо не понимаю. Компилер g++, меряю через GetTickCount. Что не так?
Может быть, с отсутствием кода gcc выравниваниет некоторые места через nop'ы, и, типа, процессор простаивает? Не втыкаю ваще :( Кто здесь мудрит: я, процессор или компилер?
肏! Τίς πέπορδε;

RawonaM

А ексепшн все-таки хоть раз бросается или нет?
Попробуй if (!key) return; и замерь время.

jvarg

Скорей всего, компилятор, в случае программного отсутствия проверки исключений, сам подставляет в код таковую. Поройтесь в настройках компилятора, обычно там такие вещи настраиваются.
Все боятся быть обвинёнными в ксенофобии. А вот в русофобии никто.
(© Захар Прилепин)

Алексей Гринь

Цитата: RawonaM от июля  8, 2009, 11:22
А ексепшн все-таки хоть раз бросается или нет?
Не выкидываются. Если бы выкидывались — я бы видел сообщение о внезапном завершении, потому что они нигде не ловятся.
肏! Τίς πέπορδε;

Gerbarius

А свой код можете выложить где-нибудь? Боюсь, без конкретного примера шансы выяснить причину замедления стремятся к нулю.

Алексей Гринь

Цитата: Gerbarius от июля  8, 2009, 11:43
А свой код можете выложить где-нибудь? Боюсь, без конкретного примера шансы выяснить причину замедления стремятся к нулю.
Да там ничего такого серьёзного.

Цитировать
template <class K, class V>
typename Map<K, V>::Node* Map<K, V>::add(K key, V value)
        {
            if(!key)
                throw NullException(1);


            if(pageCount == 0)
            {
                firstPage = lastPage = new Page();
                pageCount++;
                lastPageRatio = 0;
            }
            else if(lastPageRatio >= NEDO2_CORE_MAP_PAGE_SIZE)
            {
                Page* newPage = new Page();

                lastPage->next = newPage;
                lastPage = newPage;

                pageCount++;
                lastPageRatio = 0;
            }

            Node* node = &(lastPage->nodes[lastPageRatio++]);
                node->key = key;
                node->hash = key->hash();
                node->value = value;

            itemCount++;

            return node;
        }

Этот кусок ну совершенно никак не влияет на логику... Тест сделан так, что key никогда не бывает нулём. Да даже если и будет - вылетит эксепшн и программа закончится с сообщением а ля "This application has requested the Runtime to terminate it in an unusual way" etc. Но такого нетути.

Ничо не понимаю.
肏! Τίς πέπορδε;

Gerbarius

Я так понимаю, что key - это объект какого-то класса на самом деле? В таком случае стоит глянуть, что для него делает оператор !. Там нет случайно никаких побочных эффектов?

Алексей Гринь

Цитата: Gerbarius от июля  8, 2009, 12:28
В таком случае стоит глянуть, что для него делает оператор !
В тесте шаблонная переменная K параметризирована указателем на класс, т.е. действует логика указателя (отрицание адреса в ОЗУ). Да у того класса и operator! не перегружен вовсе.

то бишь там core::Map<core::String*, int> map;
肏! Τίς πέπορδε;

jvarg

При стандартных настройках проверка деления на нуль всегда неявно вставляется, скажем, при любых опреациях деления.

Какие-то компиляторы позволяют отключать такие приколы, какие-то - нет.
Все боятся быть обвинёнными в ксенофобии. А вот в русофобии никто.
(© Захар Прилепин)

Gerbarius

Откуда там указатель?
Почему тогда там написано
Цитировать
template <class K, class V>
typename Map<K, V>::Node* Map<K, V>::add(K key, V value)
а не
Цитировать
template <class K, class V>
typename Map<K, V>::Node* Map<K, V>::add(K *key, V value)
?

Алексей Гринь

Вместо K подставляется String*
ЦитироватьMap<String*, int> map;

В итоге вызов функции будет такой:
Цитироватьadd(String* key, int value);

Дело в том, что я не так шарю в С++, я всё больше ANSI C или Objective-C пользую. Но тут вот надо. Могу ошибаться в выборе интерфейса. Может быть, так делать не стоит. Не знаю. Язык перему́женный излишне. Его модель ООП и реализация ужасны, давлюсь но полтзуюсь сугубо из сооюражений его мейнстримности.

Чем грозит, если я ставлю так, как есть? Если подставить String или String& разницы или не будет, или не скомпилируется?

P.S. Да, глупость какая-то. Перепишу. :) Потмо сверю скорость. Но что-т не верится, что поможет.
肏! Τίς πέπορδε;

Ömer

Цитата: Алексей Гринь от июля  8, 2009, 11:12
Может быть, с отсутствием кода gcc выравниваниет некоторые места через nop'ы, и, типа, процессор простаивает? Не втыкаю ваще :( Кто здесь мудрит: я, процессор или компилер?

Так дезасемблируйте и посмотрите, как изменяется код если выкинуть ту строчку.
ya herro, ya merro

iopq

Оптимизация компилятором. Когда проверка на нуль, она проводится ПАРАЛЛЕЛЬНО. Если компилятор сам проверку делает то это он делает сразу перед использованием, т.е. не параллельно.
Poirot: Я, кстати, тоже не любитель выпить, хоть и русский.
jvarg: Профессионал? ;)

iopq

Try this and report:

template <class K, class V>
typename Map<K, V>::Node* Map<K, V>::add(K key, V value)
        {
            if(pageCount == 0)
            {
                firstPage = lastPage = new Page();
                pageCount++;
                lastPageRatio = 0;
            }
            else if(lastPageRatio >= NEDO2_CORE_MAP_PAGE_SIZE)
            {
                Page* newPage = new Page();

                lastPage->next = newPage;
                lastPage = newPage;

                pageCount++;
                lastPageRatio = 0;
            }

            Node* node = &(lastPage->nodes[lastPageRatio++]);
            if(!key)
                throw NullException(1);
                node->key = key;
                node->hash = key->hash();
                node->value = value;

            itemCount++;

            return node;
        }
Poirot: Я, кстати, тоже не любитель выпить, хоть и русский.
jvarg: Профессионал? ;)

Gerbarius

Угу, надо в ассемблер смотреть (например, можно файл скомпилировать с параметром -s и всеми остальными параметрами как обычно).
Если компилятор не шибко мудрит, то скорее всего в дело вступают всякие процессорные штучки: кэши, предсказания переходов и т.п. Но такие вещи очень трудно исследовать.

Gerbarius

Цитата: iopq от июля  8, 2009, 13:47
Если компилятор сам проверку делает
Откуда у всех такая уверенность, что компилятор непременно занимается самодеятельностью? Ему больше заняться нечем? :)

myst

Цитата: Алексей Гринь от июля  8, 2009, 11:12
Может быть, с отсутствием кода gcc выравниваниет некоторые места через nop'ы, и, типа, процессор простаивает? Не втыкаю ваще :( Кто здесь мудрит: я, процессор или компилер?
А посмотреть ассемблерный код, ты не догадался? :)

myst

Цитата: jvarg от июля  8, 2009, 12:42
При стандартных настройках проверка деления на нуль всегда неявно вставляется, скажем, при любых опреациях деления.
Вы про какой компилятор говорите?

myst

Цитата: Алексей Гринь от июля  8, 2009, 11:12
И самый прикол, что после удаления мой цикл стал отрабатывать ещё медленнее (!) на 40 мс.
Тебе прям кровь из носу надо 40 мс сэкономить? :)

jvarg

Цитата: Gerbarius от июля  8, 2009, 14:00
Цитата: iopq от июля  8, 2009, 13:47
Если компилятор сам проверку делает
Откуда у всех такая уверенность, что компилятор непременно занимается самодеятельностью? Ему больше заняться нечем? :)

Это уверенность от знания общих тенденций создания компиляторов.

Подавляющее большинство их пользователей - это прикладные программисты. Их волнует не скорость работы, а надежность и удобство разработки. Соответестенно, все настройки по умолчанию расчитаны на них.

Если вы пытаетесь делать что-то нестандартное - изменяйте настройки по умолчанию, рассчитанные на большинство.
Все боятся быть обвинёнными в ксенофобии. А вот в русофобии никто.
(© Захар Прилепин)

Gerbarius

У си/си++ другая идеология. Эти языки позволяют программисту очень многое, но и вся ответственность за качество программы ложится на него. Кстати, gcc не вставляет никаких проверок даже для деления на ноль. Только в том случае, когда ты в коде запишешь деление на ноль как на константу, компилятор выдаст предупреждение, но не ошибку! И уж точно он не проверяет указатели.

myst

Цитата: jvarg от июля  8, 2009, 17:16
Это уверенность от знания общих тенденций создания компиляторов.
То есть это было чисто умозрительное суждение? :o

myst

Цитата: Gerbarius от июля  8, 2009, 17:37
Кстати, gcc не вставляет никаких проверок даже для деления на ноль.
И не только gcc. Кстати, gcc ещё довольно предупредителен. :)

jvarg

Цитировать
Кстати, gcc не вставляет никаких проверок даже для деления на ноль.
Не верю. Это стандартная настройка по умолчанию ЛЮБОГО компилятора, любого языка. Только в некоторых эту опцию отключить нельзя, а в некоторых можно.


Конкретно с gсс я не работал (ибо давно забросил программерство), но во всех предыдущих инкарнациях С++ был в настройках раздел типа "exeption handling", где вся эта фигня настраивалась, и по умолчанию были включены все проверочные подстановки кода... 
Все боятся быть обвинёнными в ксенофобии. А вот в русофобии никто.
(© Захар Прилепин)

jvarg

Кстати, движок форума не дает мне вставить "g плюс плюс", где вместо "плюс" стоит "+".

Выдает:

Forbidden
You don't have permission to access /index.php on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
________________________________________
Apache/1.3.41 Server at //www.lingvoforum.net Port 80

Все боятся быть обвинёнными в ксенофобии. А вот в русофобии никто.
(© Захар Прилепин)