Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Всем привет!
T_B>GCC 3.4.x. Пришли к тому, что следующая функция занимает 12% всего времени выполнения программы:
На скорость может влиять в худшую сторону то, что ты тут доступаешься к массиву.
Обычно L1 кэш линейки все заняты, придется из кэша выкидывать какие-то другие
данные. Т.е. лишнего доступа к памяти желательно избежать если важна скорость.
> Возможна ли еще более быстрая реализация? О сокращении числа вызовов > (10М+) — думаем.
?
K>Если следовать идеям, который указаны по ссылке, то получаем такой код:
что то я стормозил
оказывается по ссылке уже был нужный код, просто я посмотрел на функцию hex2bin,
а bin2hex чего то не заметил
Ну в общем утро субботы, так что это простительно
Re[3]: Быстрейший способ конвертации int в hex-строку
Опять же требуются маленькие (?) добренькие индейцы, и вообще всё это UB. Зато избавились от обращения по невыровненным адресам. Кто хочет побенчмаркить?
P. S. Если всё так плохо, то, может, лучше переписать сие сразу на асме?
P. P. S. compl[ie]ment — разные слова
P. P. P. S. Как кино?
До последнего не верил в пирамиду Лебедева.
Re[4]: Быстрейший способ конвертации int в hex-строку
Здравствуйте, Roman Odaisky, Вы писали:
RO>А я попробовал — и компиляторы (а какой, кстати, использует автор?) выказали мало желания инлайнить эти вложенные функции.
byte2hex все заинлайнились (VC7.1 /O2)
>Вроде лучше так:
[...]
возможно.
бенчмаркить надо.
RO>P. P. S. compl[ie]ment — разные слова
+1
RO>P. P. P. S. Как кино?
Смотрел Клерки-2. Редкостное дерьмо.
Re: Быстрейший способ конвертации int в hex-строку
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Возможна ли еще более быстрая реализация? О сокращении числа вызовов (10М+) — думаем.
А можно сформулировать задачу в более общем виде? Почему нельзя использовать crt? Можно ли отказаться от табличной подстановки? Какова таблица символов на целевой машине? Это должно быть переносимо?
Имхо, если вы уперлись в предел производительности, то оптимизация возможна только под конкретную машину. Кстати, какой на ней тип процессора?
... << Пикник — Мы как трепетные птицы (на польском языке) (бонус-трек)>>
Re: Быстрейший способ конвертации int в hex-строку
Да будет начато тестирование...
Мне удалось ускорить первоначалльный вариант в 2.4 раза. Резервы для дальнейшего обдумывания еще есть.
const unsigned short s_hexCharsUS[256] =
{
0x3030,0x3130,0x3230,0x3330,0x3430,0x3530,0x3630,0x3730,0x3830,0x3930,0x4130,0x4230,0x4330,0x4430,0x4530,0x4630,
0x3031,0x3131,0x3231,0x3331,0x3431,0x3531,0x3631,0x3731,0x3831,0x3931,0x4131,0x4231,0x4331,0x4431,0x4531,0x4631,
0x3032,0x3132,0x3232,0x3332,0x3432,0x3532,0x3632,0x3732,0x3832,0x3932,0x4132,0x4232,0x4332,0x4432,0x4532,0x4632,
0x3033,0x3133,0x3233,0x3333,0x3433,0x3533,0x3633,0x3733,0x3833,0x3933,0x4133,0x4233,0x4333,0x4433,0x4533,0x4633,
0x3034,0x3134,0x3234,0x3334,0x3434,0x3534,0x3634,0x3734,0x3834,0x3934,0x4134,0x4234,0x4334,0x4434,0x4534,0x4634,
0x3035,0x3135,0x3235,0x3335,0x3435,0x3535,0x3635,0x3735,0x3835,0x3935,0x4135,0x4235,0x4335,0x4435,0x4535,0x4635,
0x3036,0x3136,0x3236,0x3336,0x3436,0x3536,0x3636,0x3736,0x3836,0x3936,0x4136,0x4236,0x4336,0x4436,0x4536,0x4636,
0x3037,0x3137,0x3237,0x3337,0x3437,0x3537,0x3637,0x3737,0x3837,0x3937,0x4137,0x4237,0x4337,0x4437,0x4537,0x4637,
0x3038,0x3138,0x3238,0x3338,0x3438,0x3538,0x3638,0x3738,0x3838,0x3938,0x4138,0x4238,0x4338,0x4438,0x4538,0x4638,
0x3039,0x3139,0x3239,0x3339,0x3439,0x3539,0x3639,0x3739,0x3839,0x3939,0x4139,0x4239,0x4339,0x4439,0x4539,0x4639,
0x3041,0x3141,0x3241,0x3341,0x3441,0x3541,0x3641,0x3741,0x3841,0x3941,0x4141,0x4241,0x4341,0x4441,0x4541,0x4641,
0x3042,0x3142,0x3242,0x3342,0x3442,0x3542,0x3642,0x3742,0x3842,0x3942,0x4142,0x4242,0x4342,0x4442,0x4542,0x4642,
0x3043,0x3143,0x3243,0x3343,0x3443,0x3543,0x3643,0x3743,0x3843,0x3943,0x4143,0x4243,0x4343,0x4443,0x4543,0x4643,
0x3044,0x3144,0x3244,0x3344,0x3444,0x3544,0x3644,0x3744,0x3844,0x3944,0x4144,0x4244,0x4344,0x4444,0x4544,0x4644,
0x3045,0x3145,0x3245,0x3345,0x3445,0x3545,0x3645,0x3745,0x3845,0x3945,0x4145,0x4245,0x4345,0x4445,0x4545,0x4645,
0x3046,0x3146,0x3246,0x3346,0x3446,0x3546,0x3646,0x3746,0x3846,0x3946,0x4146,0x4246,0x4346,0x4446,0x4546,0x4646
};
bool putLong4 (char *buffer, int value)
{
unsigned short* out = (unsigned short*)buffer;
unsigned int x = value;
if (buffer)
{
out[3] = s_hexCharsUS[ x & 0xFF ];
x >>= 8;
out[2] = s_hexCharsUS[ x & 0xFF ];
x >>= 8;
out[1] = s_hexCharsUS[ x & 0xFF ];
x >>= 8;
out[0] = s_hexCharsUS[ x ];
}
return !!buffer;
}
P.S. Как выложить на форум тестовую программку? Сделал давеча. Как ее залить, чтоб желающие смогли проверить на других платформах и архитектурах? (У меня винда и AMD Athlon 2000).
[EOF]
Let it be! — Давайте есть пчелу!
Re[5]: Быстрейший способ конвертации int в hex-строку
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, Roman Odaisky, Вы писали:
RO>>А я попробовал — и компиляторы (а какой, кстати, использует автор?) выказали мало желания инлайнить эти вложенные функции.
K>byte2hex все заинлайнились (VC7.1 /O2)
>>Вроде лучше так: K>[...] K>возможно. K>бенчмаркить надо.
Я уже того. Накропал программу. Как ее забросить на форум?
[EOF]
Let it be! — Давайте есть пчелу!
Re[2]: Быстрейший способ конвертации int в hex-строку
debug версии прошли все ассерты нормально
release, speed optimizations:
VC6:
TESTVER=0 — 49181 msec (itoa почти в 4 раза быстрее, но не умеет делать padding нулями слева)
TESTVER=1 — 1350 msec
TESTVER=2 — 580 msec
TESTVER=3 — 430 msec
Кстати забавно — если проставить тип вызова __fastcall вместо дефолтового __cdecl то скорость работы 2 и 3 значительно увеличивается для VC6 и уменьшаются для iCPP
Re[6]: Быстрейший способ конвертации int в hex-строку
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>GCC 3.4.x. Пришли к тому, что следующая функция занимает 12% всего времени выполнения программы: T_B>... T_B>Возможна ли еще более быстрая реализация? О сокращении числа вызовов (10М+) — думаем.
А зачем вообще этот массив? Для преобразования тетрады числа в шестнадцатеричный символ достаточно вот этого:
int t;
char str[9] = "";
// ...
str[i] = ( ( t = n & ( 0x0F << i * 4 ) >> i * 4 ) < 0x0A ? '0' : 'A' - 0x0A ) + t;
Имеем четыре константы (пропишутся в код), четыре однотактовых арифметических операции и одну операцию сравнения с возможностью предсказания ветвления ( чаще будет случаться "< 0x0A" ). Операция с памятью — прописывание символа.
По сравнению с исходным кодом, добавились две арифметических операции и операция сравнения, но исчезло обращение к памяти к двумерному массиву (а это плюс две арифметических операции).
Такие простые вычисления в регистрах пойдут быстрее, чем обращения к памяти. А цикл компилятор и сам развернёт.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re[3]: Быстрейший способ конвертации int в hex-строку
Xander Zerge wrote:
> T_B>GCC 3.4.x. Пришли к тому, что следующая функция занимает 12% всего > времени выполнения программы: > T_B>... > T_B>Возможна ли еще более быстрая реализация? О сокращении числа вызовов > (10М+) — думаем. > > А зачем вообще этот массив? Для преобразования тетрады числа в > шестнадцатеричный символ достаточно вот этого: > > int t; > char str[9] = ""; > // ... > str = ( ( t = n & ( 0x0F << i * 4 ) >> i * 4 ) < 0x0A ? '0' : 'A' — 0x0A ) + t; > > Имеем четыре константы (пропишутся в код), четыре однотактовых > арифметических операции
С тактами вопрос тонкий. На суперскалярных процессорах несколько инструкций
выполняются параллельно, поэтому такты теряют смысл, говорят о instruction
throughput and latency.
> и одну операцию сравнения с возможностью > предсказания ветвления ( чаще будет случаться "< 0x0A" ). Операция с > памятью — прописывание символа.
Здравствуйте, apple-antonovka, Вы писали:
AA>Вариант на асме — даже медленнее чем оригинальный вариант от Tuo_Bellas в VC6. Скока мона твердить миру — не соревнуйтесь с компиляторами
Ну в общем-то да)) , примерно в 2 раза. Но зато таблица всего 17 байт (которую можно уменьшить до 16), против 256*2 у 2-го варианта (разница ~30 раз) и 65536*4 у 3-го варианта (разница ~15000 раз!).
А компилятор тут скорее всего ни при чем. Четко прослеживается зависимость скорости от размера таблицы. Чем больше таблица, тем меньше кода, следовательно работы компилятору и оптимизатору. Причем заметно, что для небольшого увеличения скорости нужно существенно увеличить размер таблицы.
Может кто-нибудь еще быстрее напишет?)