| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > hex to int |
| Автор: GoldFinch 6.2.2011, 18:05 | ||||||||
| Надо написать быструю функцию парсинга шестнадцатеричных чисел. Язык - С++0х (MSVC2010), платформа - win32 код для замера производительности:
тест моего велосипеда и strtol
опции компиляции:
результаты
что написать, чтоб было еще быстрее? |
| Автор: bsa 6.2.2011, 21:02 |
| Если только развернуть цикл... |
| Автор: volatile 6.2.2011, 23:41 |
| У Вас ошибка в программе. *pos - это чар, причем сигнед чар. Диапазон [-128..127] При встрече символов из саршей части таблицы, программа будет обращаться неизвестно куда. |
| Автор: mes 7.2.2011, 00:23 |
поправка: причем может быть сигнед чар (зависит от компилятора) |
| Автор: volatile 7.2.2011, 00:31 |
| Автор: GoldFinch 7.2.2011, 00:40 |
| volatile, спасибо |
| Автор: volatile 7.2.2011, 02:03 |
| GoldFinch, да ничего, со всяким бывает. Кстати в MSVС есть опция, кажется '/J' установить char по умолчанию unsigned. А насчёт оптимизации, тут врядли что-то можно еще придумать, имхо. hexNum = hexNum * 16 + value; ==> hexNum = (hexNum << 4) | value; Но, оптимизатор и так такие вещи хорошо отлавливает. |
| Автор: mes 7.2.2011, 11:00 | ||||
Добавлено через 5 минут и 20 секунд
а для "красоты кода" как минимум инкрементацию счетчика удобнее поместить в оглавление цикла.. |
| Автор: xvr 7.2.2011, 12:11 |
| Попробовать задействовать SSE (обрабатывать по несколько символов одновременно) |
| Автор: GoldFinch 7.2.2011, 13:47 |
| xvr, как? |
| Автор: xvr 7.2.2011, 16:24 | ||
Надо смотреть доки, их там много Не уверен, что это даст выигрышь, т.к. набор 4х цифр в регистр может съесть весь прирост производительности |
| Автор: GoldFinch 7.2.2011, 17:28 |
| xvr, основные проблемы - это найти конец числа, и упаковать байты в полубайты. это убивает все плюсы от распараллеливания. |
| Автор: xvr 7.2.2011, 19:33 | ||||
Упаковать полубайты в байты SSE может, а вот с нахождением конца числа - облом. Чистым SSE тут не обойтись
|
| Автор: borisbn 7.2.2011, 19:51 | ||||||
Очень хочется избавиться от if внутри цикла. М.б. хранить в массиве метки (labels), т.е. адреса перехода, и делать
в таблице вместо -1 хранить метку по которой будет код
а в "полезных" ячейках хранить метку по которой будет код
вот только придётся делать на ассемблере, и, честно говоря, я не знаю как это сделать и можно ли вообще P.S. Сделать то же самое switch'ем на 256 значений не удалось - смотрел ассемблерный код, сгенерённый компилятором (правда VS2008, а не 2010) - там тоже cmp и ja в цикле |
| Автор: GoldFinch 7.2.2011, 19:59 |
| borisbn, это плохое решение. условный переход по известному адресу лучше перехода по неизвестному. |
| Автор: mes 7.2.2011, 20:48 |
| GoldFinch, если *16 убрать (допустим заменив на +16), производительность сильно увеличивается ? если да, то "полезный" ряд (где не -1) таблицы можно сделать косвенным, и представить как отображение на двухмерный массив чисел, значение которого равно pow (0x10, строка) +столбец. тогда для 4х-значных 16-ричных чисел потребуется 4*16*sizeof(int) дополнительной памяти и одно косвенное обращение к ней.. Добавлено @ 20:50 если ничего не напутал |
| Автор: borisbn 7.2.2011, 21:10 |
| GoldFinch, вообще-то так и предполагал, но точно не знал. Жалко. А у меня ещё столько идей ... (С) какой-то анекдот про Вовочку |
| Автор: mes 8.2.2011, 01:33 |
вот накалякал, развернув цикл: http://liveworkspace.org/code/3884c626a7058a262594cf3ea895ebe5 осталось сравнить по скорости.. |
| Автор: GoldFinch 8.2.2011, 02:27 |
| mes, там должно быть 8 цифр, а не 4. если сделать 8 - то производительность будет такой же как и в моей версии. http://paste.org.ru/?wixlwl |
| Автор: mes 8.2.2011, 10:09 |
да, я вчера чего то упустил из виду, что *16 и так оптимальное.. так что tabled_mul излишний.. так что надежда могла быть лишь на исключение лишний операций, при развороте цикла.. хотя исключение пары сдвигов на общем фоне заметно не будет.. так же как и пользы от замены "+" на "|"... |
| Автор: volatile 9.2.2011, 00:49 | ||
| Сегодня немного повозился с вашей функцией. оптимизировать её практически бесполезно, так как на вызов/возврат тратится больше времени. чем собственно на само тело функцию. Если есть возможность ее надо вызывать инлайн. Но тем не менее, вот что получилось:
Результаты по времени на моём компе. исходный вариант - 100% этот вариант ~ 84.8% |