Здравствуйте, ravik, Вы писали:
R>Это фрагмент типа эдакого деления. На самом деле на каждой итерации ищется сочетание полей переменной r пользовательского типа и некоторого шаблона, который сам может динамически и скачкообразно измениться. Все приведенные арифметические операторы и операторы сравнения перегружены, то есть компилятор вызывает другие методы, а там внутри тоже может попасться какой-нибудь вызов. Что делает этот код? Он берет вершину "числа" (на самом деле это закодированная структура) и помаленечку от не "откусывает" порцию-константу (с некоторым приближением это "делитель") — наблюдая, не произойдет ли совпадения с шаблоном (r.m_number > 0).
Ну я хз, что там внутри, пока ничего криминального не вижу.
R>Для прикладника упоминаемого проекта идея, запечатленная в этом куске кода очень наглядна. "Деление" — это метафора проекта. А с точки зрения производительности — полная катастрофа. Я предложил подрихтовать способ контроля за шаблоном, практически объединив перегрузки операторов и контроль шаблона в одну процедуру. Там около 1 тыс. ассемблерных инструкций. Так что простите душевно, для анализа icc моего энтузиазма не хватило.
А что, нельзя это сделать на цпп? Ассемблер тут не нужен.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, ravik, Вы писали:
_NN>Вы недооцениваете оптимизации компилятора. _NN>Если правильно расставить constexpr, noexcept, определить операции перемещения и использовать соответствующие ключи компиляции, то результат зачастую превзойдёт ваши ожидания.
_NN>Конечно имеются моменты где этого недостаточно, но я бы не стал бежать в ассемблер не выжав максимум из того что есть.
Ну... такие были обстоятельства. Мы все принимаем решения и несем потом за них ответственность.
Кстати! Думая о том, какую пользу могло бы привести обсуждение простенького вопроса, а я бы теперь назвал начатую тему "почему я закамуфлировал оператор goto под ассемблер и возмущен поведением своего компилятора?!", мне хочется у Вас спросить.
Нет ли у Вас в знакомых сильного математика-алгоритмиста? Из проекта, из-за которого здесь сыр-бор, я вынес кое-что для себя лично, и мне хотелось бы обсудить это с профессионалом. У меня есть предчувствие, что эта штучка может дорого стоить. Интуиция. А я по чистой случайности владею небольшой компьютерной компанией, и будучи убежденным, что это действительно стоит того, мог бы привлечь ресурсы под проект.
Здравствуйте, T4r4sB, Вы писали:
TB>А что, нельзя это сделать на цпп? Ассемблер тут не нужен.
Там весь проект на C++, и он достаточно крупный. Ассемблер в нем сущая мелочь, появившаяся на этапе, когда захотелось взглянуть одним глазком, "а что там может быть дальше", а проект, выполнивший основную задачу, подпрыгнуть не мог. Нам показалось, что ассемблер в этой ситуации это то, что называется "дешево и с огоньком". Вообще-то, я в полной удовлетворенности по результатам. Я ведь сначала "победил" проблему. И только потом, когда вместе со всей страной валяюсь под елкой, захотелось спросить у умных людей, почему мне компилятор новогоднюю свинью подложил?!
Здравствуйте, _NN_, Вы писали:
L>>Вполне может быть, но своим опытом пока ни подтвердить, ни опровергнуть не могу. _NN> Классическая задачка на перебор двумерного/многомерного массива.
Хрестоматийные примеры, конечно, хорошо. Но вот на практике мне лично пока не доводилось выжимать производительность оптимизацией использования кеша.
Здравствуйте, ravik, Вы писали:
R>Приветствую, коллеги! Не могу понять в чем проблема — в Debug все работает как надо, в Release — неправильно. Как выйти из ситуации — знаю, в чем причина — так и не пойму.
Здравствуйте, Сергей Мухин, Вы писали:
СМ>Здравствуйте, ravik, Вы писали:
R>>Приветствую, коллеги! Не могу понять в чем проблема — в Debug все работает как надо, в Release — неправильно. Как выйти из ситуации — знаю, в чем причина — так и не пойму.
На сегодняшние 4 истекшие дня нового года этот ответ в рейтинге сделанных мне подарков занял I место. Спасибо тебе, добрый человек!
P.S. Приготавливаясь к вечернему приятному чтению, увидел мельком, что автор статьи занимается оптимизаторами прямо с моего года рождения. Вспомнил, что однажды, очутившись в провальном проекте, заказал 10 экземпляров Брукса на books.ru, и раздарил его ключевым участникам.
Здравствуйте, ravik, Вы писали:
R>Здравствуйте, T4r4sB, Вы писали:
TB>>А что, нельзя это сделать на цпп? Ассемблер тут не нужен.
R>Там весь проект на C++, и он достаточно крупный. Ассемблер в нем сущая мелочь, появившаяся на этапе, когда захотелось взглянуть одним глазком, "а что там может быть дальше", а проект, выполнивший основную задачу, подпрыгнуть не мог. Нам показалось, что ассемблер в этой ситуации это то, что называется "дешево и с огоньком".
Рефакторинг кода — это "дёшево и с огоньком", а ассемблерная каша на 1000 строк это нифига не дёшево.
Здравствуйте, landerhigh, Вы писали:
L>Хрестоматийные примеры, конечно, хорошо. Но вот на практике мне лично пока не доводилось выжимать производительность оптимизацией использования кеша.
Мне тоже.
Обычно решение через изменение алгоритма или подхода даёт больший эфект
Во всяком случае это не повод писать пессимизацию заранее вроде как iterator++ вместо ++iterator.
Здравствуйте, T4r4sB, Вы писали:
TB>Рефакторинг кода — это "дёшево и с огоньком", а ассемблерная каша на 1000 строк это нифига не дёшево.
У меня в прошлом году история была. В нулевых я работал на крупную компанию и писал им расширенные процедуры под "сиквел". И нужно там было перехватывать BLOB в клиентском соединении и сохранять в файловой системе. И наоборот, заталкивать дисковый файл в клиентский поток. Это была подрядная система документооборота, с плотностью несколько десятков тысяч документов в год. И все там до сих пор работало хорошо, пока не выяснилось, что другие программисты, которые писали клиента на VB — тогда же, десять лет назад, — закопипастили код из инета, но "потеряли" при этом правильную диррективу прекомпиляции Option Base. В результате мой код сохранял на каждый 4К-блок паразитный 4097-й байт. Ошибка вскрылась, когда они решили клиента переписать. Представляете, полмиллиона документов, и все кривые.
Так что рефакторинг в наших условиях штука тонкая. Я всю жизнь старался писать код из соображений, что кто-нибудь будет его менять. Но это срабатывает, только когда все поддерживаются подобной культуры. Поймите, меня это печалит, но я воспринимаю как реальность.
Здравствуйте, ravik, Вы писали:
R>Нет ли у Вас в знакомых сильного математика-алгоритмиста? Из проекта, из-за которого здесь сыр-бор, я вынес кое-что для себя лично, и мне хотелось бы обсудить это с профессионалом. У меня есть предчувствие, что эта штучка может дорого стоить. Интуиция. А я по чистой случайности владею небольшой компьютерной компанией, и будучи убежденным, что это действительно стоит того, мог бы привлечь ресурсы под проект.
R>На сегодняшние 4 истекшие дня нового года этот ответ в рейтинге сделанных мне подарков занял I место. Спасибо тебе, добрый человек! R>
Существует еще один вариант, не пользующийся, впрочем, большой популярностью у публики.
Не использовать debug сборку и отладчик при разработке. Совсем.
Здравствуйте, ravik, Вы писали:
R>Так вот, в режиме Debug работает как надо, а в Release внешний метод возвращает в код клиента пустой (сконструированный по умолчанию, нулевой) объект типа kint. Я вставил вместо предположительно бажной строки прямо блоком тело второго метода, но, блин, почему так выходит-то?
Поищи возможные причины:
1. Не инициализирована m_uiPos или this->m_arr[0] или Operand.m_arr[0].
2. Где-то портится память.
3. Оптимизация, сделанная компилятором, изменила твою ассемблерную вставку или данные, с которыми она работает.
Здравствуйте, AleksandrN, Вы писали:
AN>Здравствуйте, ravik, Вы писали:
R>>Так вот, в режиме Debug работает как надо, а в Release внешний метод возвращает в код клиента пустой (сконструированный по умолчанию, нулевой) объект типа kint. Я вставил вместо предположительно бажной строки прямо блоком тело второго метода, но, блин, почему так выходит-то?
AN>Поищи возможные причины: AN>1. Не инициализирована m_uiPos или this->m_arr[0] или Operand.m_arr[0]. AN>2. Где-то портится память. AN>3. Оптимизация, сделанная компилятором, изменила твою ассемблерную вставку или данные, с которыми она работает.
Спасибо, разобрались вроде. Джамп из ассемблерной вставки передавал управление по метке во внешний си-код, а это ни что иное, как goto через границу блока со всеми вытекающими. В MSDN написано, что, встретив ассемблерную вставку, компилятор никак ее не анализирует и вставляет ее "как-есть".
Здравствуйте, T4r4sB, Вы писали:
R>>Там весь проект на C++, и он достаточно крупный. Ассемблер в нем сущая мелочь, появившаяся на этапе, когда захотелось взглянуть одним глазком, "а что там может быть дальше", а проект, выполнивший основную задачу, подпрыгнуть не мог. Нам показалось, что ассемблер в этой ситуации это то, что называется "дешево и с огоньком".
TB>Рефакторинг кода — это "дёшево и с огоньком", а ассемблерная каша на 1000 строк это нифига не дёшево.
Здравствуйте, ravik, Вы писали:
R>Спасибо, разобрались вроде. Джамп из ассемблерной вставки передавал управление по метке во внешний си-код, а это ни что иное, как goto через границу блока со всеми вытекающими. В MSDN написано, что, встретив ассемблерную вставку, компилятор никак ее не анализирует и вставляет ее "как-есть".
ИМХО, если нужен ассемблер в коде на C или С++, то лучше делать не вставками, а написать на ассемблере функцию и компилировать в объектный код. А в C/C++ части — прототип функции и прилинковывать ассемблерный код при сборке проекта.