Re[9]: Помогите оценить код
От: Andrew S Россия http://alchemy-lab.com
Дата: 28.08.07 22:21
Оценка:
RO>А вообще, засунул бы функции в классы и проверил бы сам.
RO>Получается интересно:
RO>3872588475 — хитрые битовые операции
RO>3935120400 — таблица unsigned[65536]


Ну дык я, конечно, проверил
У меня на самом деле получился твой вариант быстрее процентов на 20, чем приведенный мной. Но ввиду оверхеда на память, который он привносит, а также некоторых других "мелочей" (например, чтение сампла из памяти тоже приличный оверхед для приведенного мной алгоритма) полагаю, что по производительности они примерно равны на текущих "обычных" системах, а вот по функциональности приведенный мной вариант выигрывает _значительно_. Хочу напомнить, что это ни в коем случае не мой вариант, я лишь "разместил объяву". Авторство (а точнее, точку инстанцирования) я указал ранее.

RO>Вывод: твою функцию в топку, мою функцию в топку, использовать std::bitset::count, пока не выяснится, что программа проводит в ней непристойно много времени.


Ну... Кому что. Я работаю в области, где часто требуется эффективность, поэтому для меня подобные спички часто бывают актуальны. Впрочем, задачи, где бы требовалось подсчитать (именно подсчитать) количество единичных бит мне пока что не встречалось, так что все это имеет чисто академический интерес. Но знать о подобных алгоритмах, имхо, просто необходимо.
Например, в том же bitset::count во многих реализациях используется табличный метод (группы по 4-8 бит). Т.е. используй кандидат битсет, получил бы примерно в 2-3 раза более эффективную функцию вообще безо всяких усилий.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[6]: Помогите оценить код
От: Erop Россия  
Дата: 29.08.07 04:58
Оценка: 1 (1)
Здравствуйте, Andrew S, Вы писали:

AS>>>Речь идет о знании алгоритмов (не их реализации, а вообще существовании), а не "хрени в комментах". Из моего сообщения это очевидно.

E>>1) ИМХО, не важно знает ли кандидат такой алгоритм или нет.
AS>Опять передергиваете. Перечитайте то, на что отвечаете, нужное выделено.
Ну правда не важно. Важно чтобы программировать умел. А знает какой-то конкретный алгоритм или нет, да какая разница? Не знает -- узнает. А не узнает, то ничего драматического не случится, ИМХО.

AS>Да при чем тут комменты — смысл в том, что надо понимать, что это далеко не оптимальная реализация.

AS>но вот в комментах написать, что это просто набросок и настоящая реализация так не должна работать, имхо, стОило.

AS>Судя по коду (то, что например, это шаблонная функция), кандидат об этом не задумывался.
Вообще-то говоря, какой вопрос, такой и ответ, ИМХО.

AS>Это вопрос не ко мне, а к топиккастеру.

Ну отвечал-то ты
Надеюсь, что теперь тебе понятно с чем я был согласен
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Помогите оценить код
От: CreatorCray  
Дата: 29.08.07 06:30
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Да пожалуйста, тоже увеличил.

AS>
AS>VC6
AS>23384774
AS>43100993
AS>VC7.1
AS>17996589
AS>20148363
AS>


AS>Итого — у меня мой варианта _всегда_ быстрее. Вариант Романа, к сожалению, имеет довольно мало средств для оптимизации — тут практически не могут спариваться команды, да и выборка из памяти дело тормознутое.

AS>Но как собственно VC7 смог так улучшить вариант 2? Посмотрим.
Улучшить? Да он его хреново скомпилил.
Сравни:

AS>countOnes

AS>
AS>    lea    edx, DWORD PTR [eax-1]
AS>    mov    ebx, edx
AS>    shr    ebx, 24                    ; 00000018H
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    lea    esi, DWORD PTR [eax-2]
AS>    mov    DWORD PTR tv1199[esp+48], esi
AS>    shr    esi, 24                    ; 00000018H
AS>    movzx    esi, BYTE PTR _ones[esi]
AS>    add    esi, ebx
AS>    lea    ecx, DWORD PTR [eax+1]
AS>    mov    ebx, ecx
AS>    shr    ebx, 24                    ; 00000018H
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    lea    ebx, DWORD PTR [eax-2]
AS>    and    ebx, 255                ; 000000ffH
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    lea    ebx, DWORD PTR [eax-1]
AS>    and    ebx, 255                ; 000000ffH
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    mov    ebx, eax
AS>    shr    ebx, 24                    ; 00000018H
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    movzx    ebx, ah
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    movzx    ebx, BYTE PTR tv1023[esp+50]
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    movzx    ebx, ch
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    mov    DWORD PTR tv1192[esp+48], edx
AS>    add    esi, ebx
AS>    movzx    edx, dh
AS>    movzx    edx, BYTE PTR _ones[edx]
AS>    mov    DWORD PTR tv1180[esp+48], ecx
AS>    movzx    ebx, BYTE PTR tv1180[esp+50]
AS>    movzx    ebx, BYTE PTR _ones[ebx]
AS>    add    esi, ebx
AS>    add    esi, edx
AS>    movzx    edx, BYTE PTR tv1192[esp+50]
AS>    movzx    edx, BYTE PTR _ones[edx]
AS>    add    esi, edx
AS>    movzx    edx, BYTE PTR tv1199[esp+49]
AS>    movzx    edx, BYTE PTR _ones[edx]
AS>    add    esi, edx
AS>    movzx    edx, BYTE PTR tv1199[esp+50]
AS>    movzx    edx, BYTE PTR _ones[edx]
AS>    and    ecx, 255                ; 000000ffH
AS>    movzx    ecx, BYTE PTR _ones[ecx]
AS>    add    esi, edx
AS>    mov    edx, eax
AS>    add    esi, ecx
AS>    and    edx, 255                ; 000000ffH
AS>    movzx    ecx, BYTE PTR _ones[edx]
AS>


и

movzx ebp, al
movzx edx, BYTE PTR ?ones$0@@4QBEB[ebp]
mov ebp, eax
shr ebp, 8
and ebp, 255
movzx ebp, BYTE PTR ?ones$0@@4QBEB[ebp]
add edx, ebp
mov ebp, eax
shr ebp, 16
and ebp, 255
movzx ebp, BYTE PTR ?ones$0@@4QBEB[ebp]
add edx, ebp
mov ebp, eax
shr ebp, 24
movzx ebp, BYTE PTR ?ones$0@@4QBEB[ebp]
lea ebx, DWORD PTR [edx+ebp]


AS>Как мы видим, тут просто развернули цикл (пачками по 4).

AS>Полагаю, IC сделал примерно то же
Как ты сам можешь видеть — ICC ничего не разворачивал.
AS>, поскольку больше увеличить производительность в данном варианте нечем (только работать с 32-х битным массивом, но там прибавка не будет большой).

Вообще результат компиляции countOnes вижуалкой кроме как кошмарным назвать не могу. Зачем он лишний раз читает/пишет в tv1<xxx>? И что это вообще за переменные то? В результате больше обращений к памяти чем нужно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[8]: Помогите оценить код
От: Аноним  
Дата: 29.08.07 07:52
Оценка: -1
AS>Что за народ пошел — все только просят привести решение, а подумать самим лень

удивительная особенность человека — как только начинаешь его о чем то просить, он начинает, как бы это сказать помягче... выделываться

AS>В общем, даже и не собираюсь — у меня полно других дел, помимо изобретательств никому не нужных шаблонов. Если вам действительно требуется такая функциональность — вы и делайте, где взять алгоритм и объяснение его работы я уже сказал. Из алгоритма возможность его реализации для любых 2^n битных значений вытекает очень явно


"Назвался груздем — полезай в кузов." Вам представили универсальный работающий пример, вы же утверждаете, что знаете БОЛЕЕ эффективный...
Покажите полный законченый аналог (по работе) и превосходящий по эффективности. Все остальное — слова!
Re[9]: Помогите оценить код
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.08.07 08:46
Оценка:
AS>>В общем, даже и не собираюсь — у меня полно других дел, помимо изобретательств никому не нужных шаблонов. Если вам действительно требуется такая функциональность — вы и делайте, где взять алгоритм и объяснение его работы я уже сказал. Из алгоритма возможность его реализации для любых 2^n битных значений вытекает очень явно

А>"Назвался груздем — полезай в кузов." Вам представили универсальный работающий пример, вы же утверждаете, что знаете БОЛЕЕ эффективный...

А>Покажите полный законченый аналог (по работе) и превосходящий по эффективности. Все остальное — слова!

Я показал полный и законченый вариант. Если у Вас не хватает знаний, чтобы это оценить — это Ваши, а не мои, проблемы.

В общем, дорогой Аноним. Еще раз и по слогам — даже не собираюсь, тем более с таким тоном общения. Если Вам это интересно — реализуйте и представьте результаты — где найти нужные знания, я уже сказал. Если же Вы просто тут для того, чтобы пофлеймить (а я в этом уверен с первого же Вашего сообщения) — для этого на rsdn есть специальные места. Подите в игнор.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Помогите оценить код
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.08.07 08:57
Оценка:
AS>>Итого — у меня мой варианта _всегда_ быстрее. Вариант Романа, к сожалению, имеет довольно мало средств для оптимизации — тут практически не могут спариваться команды, да и выборка из памяти дело тормознутое.
AS>>Но как собственно VC7 смог так улучшить вариант 2? Посмотрим.
CC>Улучшить? Да он его хреново скомпилил.

Именно _улучшить_. Там пачки по 4, внимательно изучите код.

AS>>Как мы видим, тут просто развернули цикл (пачками по 4).

AS>>Полагаю, IC сделал примерно то же
CC>Как ты сам можешь видеть — ICC ничего не разворачивал.
AS>>, поскольку больше увеличить производительность в данном варианте нечем (только работать с 32-х битным массивом, но там прибавка не будет большой).

CC>Вообще результат компиляции countOnes вижуалкой кроме как кошмарным назвать не могу. Зачем он лишний раз читает/пишет в tv1<xxx>? И что это вообще за переменные то? В результате больше обращений к памяти чем нужно.


Это временные переменные, в которых он собирает часть результата. На самом деле, операции со стеком в последних процессорах оптимизированы (по моим тестам, проигрыш с такими обращениями даже в основном цикле получается небольшой — порядка 7-10 процентов). К сожалению, ic у меня нет, поэтому проверить, как работает его вариант на нормальных платформах (а P4 считать за нормальную платформу сложно) я не могу. Если, конечно, бинарник кто-нибудь не выложит Ну и опять же — варианту Романа в данном тесте, как он сам и заметил, предоставляются "тепличные" условия — упорядоченное чтение. Лучше бы вы попробовали сампл Романа, заменив функции на функторы — там получается несколько правильнее.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[10]: Помогите оценить код
От: Erop Россия  
Дата: 29.08.07 08:58
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>В общем, дорогой Аноним. Еще раз и по слогам — даже не собираюсь, тем более с таким тоном общения. Если Вам это интересно — реализуйте и представьте результаты — где найти нужные знания, я уже сказал. Если же Вы просто тут для того, чтобы пофлеймить (а я в этом уверен с первого же Вашего сообщения) — для этого на rsdn есть специальные места. Подите в игнор.


Вообще-то задача выбора констант, вернее выбора момента с которого константы уже не нужны в CT не такая уж и тривильная, ИМХО...
Хотя наверное можно как-то извратиться
В конце концов протабулировать всё до 2048-битных чисел, например
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Помогите оценить код
От: Аноним  
Дата: 29.08.07 09:08
Оценка: -1
AS>Я показал полный и законченый вариант. Если у Вас не хватает знаний, чтобы это оценить — это Ваши, а не мои, проблемы.
полный, законченый пример для чего? а я думал только для 32 битных значений...

AS>В общем, дорогой Аноним. Еще раз и по слогам — даже не собираюсь, тем более с таким тоном общения. Если Вам это интересно — реализуйте и представьте результаты — где найти нужные знания, я уже сказал. Если же Вы просто тут для того, чтобы пофлеймить (а я в этом уверен с первого же Вашего сообщения) — для этого на rsdn есть специальные места. Подите в игнор.

с каким тоном общения? на неадекватное поведение — последовал адекватный ответ.
еще раз по слогам: без полного, законченного примера все вышесказанное вами только пустая болтовня. кроме как посылать по неизвестному адресу, без каких-либо комментариев к коду (кроме "есть такая книга умная — как, а, вы не читали, учите матчасть" — это как минимум тупые комментарии).
Re[11]: Помогите оценить код
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.08.07 09:19
Оценка:
AS>>В общем, дорогой Аноним. Еще раз и по слогам — даже не собираюсь, тем более с таким тоном общения. Если Вам это интересно — реализуйте и представьте результаты — где найти нужные знания, я уже сказал. Если же Вы просто тут для того, чтобы пофлеймить (а я в этом уверен с первого же Вашего сообщения) — для этого на rsdn есть специальные места. Подите в игнор.

E>Вообще-то задача выбора констант, вернее выбора момента с которого константы уже не нужны в CT не такая уж и тривильная, ИМХО...


?? В алгоритме количество шагов равно log(bit_count). Все константы на каждом шаге вычисляются как зависимость от номера шага, а результат на текущем шаге — это сумма резальтатов предыдущих шагов. Первые 3 шага (которые выполняются всегда, поскольку они считают суммы для полубайтов) несколько специфичны — надо учитывать возможные переполнения для частичных сумм. На последнем шаге выполняется отсечение частичной суммы предыдущего шага. А в целом — алгоритм рекурсивный, банальный бинарный спуск. Все это _реализуемо_ на шаблонах в CT, и результат будет полностью аналогичен "ручному" кодированию. Но тратить свое время запросто так, чтобы ублажить господина Анонима — не хочется. Поскольку ему нужен совсем не результат, это же очевидно
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[12]: Помогите оценить код
От: Erop Россия  
Дата: 29.08.07 09:27
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>...(которые выполняются всегда, поскольку они считают суммы для полубайтов) несколько специфичны — надо учитывать возможные переполнения для частичных сумм...


Собственно я про то, что начиная с какой-то длинны целого (типа 256-битное) надо не забыть сделать &0x00FF00FF00FF00FF...00FF.
Ну и сами константы сегенрить тоже надо, кстати.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Помогите оценить код
От: MasterZiv СССР  
Дата: 29.08.07 10:01
Оценка:
Аноним 617 пишет:
> В 7-ой студии это сехи ловит

Так ловить-то оно ловит, а откуда там SEH-и будут ?
Ну если ей конечно 0x01 в качестве адреса строки дать,
оно GPF даст — да. Но если просто бесконечную строку
дать, почешет по памяти до первого '\0' и не фект что
до GPF его не найдет.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Помогите оценить код
От: Andir Россия
Дата: 29.08.07 10:40
Оценка:
Здравствуйте, <Аноним>, Вы писали:

A>>Озвучте зарплату, на которую собеседовается человек, а то получится, что тут кандидата залажают, а окажется, что для рассматриваемой зарплаты он просто отлично пишет и другого такого вы не найдёте.

А>Планировалась вилка 9-15 тыс, в нашей глубинке эта зп так скажем выше среднего (не для программистов, а вообще по городу)

Это где нонче такое? Да так, что там на такую зарплату программистов в штат набирают???

С Уважением, Andir!
using( RSDN@Home 1.2.0 alpha rev. 717 ) { /* Работаем */ }
Re[13]: Помогите оценить код
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.08.07 11:05
Оценка:
AS>>...(которые выполняются всегда, поскольку они считают суммы для полубайтов) несколько специфичны — надо учитывать возможные переполнения для частичных сумм...

E>Собственно я про то, что начиная с какой-то длинны целого (типа 256-битное) надо не забыть сделать &0x00FF00FF00FF00FF...00FF.

E>Ну и сами константы сегенрить тоже надо, кстати.

Вот решение, которое полностью дублирует функционал начального кода. При 32-х битах генерируемый код — команда в команду ручная реализация pop.

template <int nCount>
struct EnumConstHelper
{
    template <class T>
    struct Dummy
    {
        enum {value = T::value};
    };
};

template <>
struct EnumConstHelper<0>
{
    template <class T>
    struct Dummy
    {
        enum {value = 0};
    };
};


template <class T, int nVal>
struct EnumConst
{
    template <int nCount>
    struct EnumConstImpl
    {
        enum {value = ((nVal << ((nCount - 1)*CHAR_BIT)) | EnumConstHelper<nCount-1>::Dummy<EnumConstImpl<nCount - 1> >::value)};
    };
    enum {value = EnumConstImpl<sizeof(T)>::value};
};


template <int iLevel>
struct CountBitsImpl
{
    template <class T>
    static unsigned DoCount(T X)
    {
        X = CountBitsImpl<iLevel - 1>::DoCount(X);
        return X + (X >> (1 << (iLevel))) ;
    }
};


template <>
struct CountBitsImpl<0>
{
    template <class T>
    static unsigned DoCount(T X)
    {
        return X - ( (X >> 1) & EnumConst<T, 0x55>::value);
    }
};

template <>
struct CountBitsImpl<1>
{
    template <class T>
    static unsigned DoCount(T X)
    {
        X = CountBitsImpl<0>::DoCount(X);
        return (X & EnumConst<T, 0x33>::value) + ((X >> 2) & EnumConst<T, 0x33>::value);
    }
};

template <>
struct CountBitsImpl<2>
{
    template <class T>
    static unsigned DoCount(T X)
    {
        X = CountBitsImpl<1>::DoCount(X);
        return (X + (X >> 4)) & EnumConst<T, 0x0F>::value;
    }
};


template <int nVal>
struct CountLevelImpl
{
    enum {value = CountLevelImpl<nVal/2>::value + 1};
};

template <>
struct CountLevelImpl<0>
{
    enum {value = 0};
};

template <int nVal>
struct CountLevel
{
    enum {value = CountLevelImpl<nVal>::value  - 1};
};

template <>
struct CountLevel<0>
{
};


template <class T>
unsigned CountBits(T X)
{
    return CountBitsImpl<CountLevel<sizeof(T)*CHAR_BIT>::value - 1>::DoCount(X) & (((unsigned)-1) >> (sizeof(int)*CHAR_BIT - CountLevel<sizeof(LONGLONG)*CHAR_BIT>::value));
};

Наверное, можно и красивее реализовать (особенно EnumConst, который заточен под VC6 — очевидным образом там надо const T value вместо enum использовать), но думать над этим откровенно не хочется.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Помогите оценить код
От: __SPIRIT__ Россия  
Дата: 06.09.07 15:01
Оценка: 1 (1) +1
Здравствуйте, MasterZiv, Вы писали:

MZ>Ладно, раз уж вам так нужно....


>> #include <iostream.h>

>> #include <string.h>

MZ>Эти заголовки давно уже не так

MZ>называются. Ну если второй еще можно (корректно)
MZ>оставлять как <string.h>, то первый по стандарту
MZ><iostream>

MZ>Т.е. это чел либо студент (работал на старых компиляторах),

MZ>либо просто работал на старых компиляторах.
MZ>Хотя работать оно будет.
MZ>Если неправ — поправьте.

Если мне память не изменяет то в 6ой студии так и пишеться.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.