Wake of Gods Forum | Форум Во Имя Богов

Full Version: С++, общая тема
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
А что смешного? Вики утверждает, что именно эта формула и используется для точного расчёта числа Пи на обычных ПК.
Я программы спрашивал, а не формулу. Хочу сравнить.
так зачем тебе программа? есть же число пи со скольки угодно знаками
Я хочу сравнить производительность разных алгоритмов вычисления числа Пи.

Само число Пи я не собираюсь вычислять, если вы это имеете в виду.
Quote:в C# элементу управления (по крайней мере, форме) можно установить двойную буферизацию. поищи это.
Quote:В плюсовой VCL тоже. this->DoubleBuffered = true, если в синтаксисе не опечатался...
Да я слышал, и уже использовал, но здесь почему то совершенно не работает!
Пробовал по разному и this->DoubleBuffered = true и DoubleBuffered = true и Form1->DoubleBuffered=true
И в разным местах: онпаинт, онкриэйт...

Сорс нужно?
etoprostoya Wrote:Я хочу сравнить производительность разных алгоритмов вычисления числа Пи.
Само число Пи я не собираюсь вычислять, если вы это имеете в виду.
Так нету этих "алгоритмов", насколько я понимаю. Это число по готовым формулам и вычисляют...

packa Wrote:Пробовал по разному и this->DoubleBuffered = true и DoubleBuffered = true и Form1->DoubleBuffered=true
И в разным местах: онпаинт, онкриэйт...
Ab
Это одна и та же запись. Потому что все "события формы" - это методы класса TForm, в котором Form1 и играет роль this. Но this - это более универсальная запись, она не изменится при переименовании Form1 в какую-нибудь my_favorite_Form. Поэтому, более каноничен первый вариант.

И прописывать это надо лишь один раз, в конструкторе формы. Почему не работает - хз. Приведи код того фрагмента, где ты раскрашиваешь всё своим "чёрным прямоугольником" (кстати, нафига?)
Может кто подскажет как оптимизировать код для alpha.dll?
Нагружает проц. вот эта функция, которая вычисляет каждый пиксель с альфа каналом
Code:
static int Draw( int Type, image *pImage, draw_info *pInfo )
{
    int screenW=GetSystemMetrics(SM_CXSCREEN);
    int screenH=GetSystemMetrics(SM_CYSCREEN);
    if( pInfo->screen_size.x != screenW || pInfo->screen_size.y != screenH )
        return OriginalDraw( Type, pImage, pInfo );

    static char LastNames[8][13] = { {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
    static int CurLastName = 0;

    if( g_bPrint )
    {
        for( int i = 0; i < 8; i++ )
            if( strcmp( pImage->name, LastNames[i] ) == 0 )
                goto draw;

        strncpy( LastNames[CurLastName], pImage->name, 12 );
        LastNames[CurLastName][12] = 0;
        aprintf( WHITE, "draw %s\n", LastNames[CurLastName] );
        CurLastName++;
        if( CurLastName >= 8 )
            CurLastName = 0;
    }
draw:

    map<image_name,new_image*>::iterator Rep = g_Replace.find( image_name(pImage->name) );
    if( Rep == g_Replace.end() )
        return OriginalDraw( Type, pImage, pInfo );

    new_image *pNewImage = Rep->second;

    // center image
    vector ImagePos = pInfo->pos - pInfo->pos0 + (pImage->total_size - pNewImage->size)/2;

    // crop image
    vector Pos = pInfo->pos;
    vector Size = pInfo->size;
    rect_cross( &Pos, &Size, ImagePos, pNewImage->size );
    rect_cross( &Pos, &Size, vector( 0, 0 ), vector( screenW, screenH ) );

    vector Pos0 = Pos - ImagePos;

    color16 *pOld = &pInfo->pscreen[Pos.y*screenW + Pos.x];
    colorRGBA *pNew;
    if( pInfo->horz_invert )
        pNew = &pNewImage->data[(Pos0.y+1)*pNewImage->size.x - Pos0.x];
    else
        pNew = &pNewImage->data[(Pos0.y  )*pNewImage->size.x + Pos0.x];
       for( int y = 0; y < Size.y; y++ )
    {
        for( int x = 0; x < Size.x; x++ )
        {
            if( ( *pNew & 0xFFFFFF ) == 0xFFFF ) // color for replacement
            {
                color16 New = pInfo->color;
                if( New )
                *pOld = MakeColor16( GetRed  (*pOld) + GetAlpha(*pNew)*(GetRed  (New) - GetRed  (*pOld))/256,
                                     GetGreen(*pOld) + GetAlpha(*pNew)*(GetGreen(New) - GetGreen(*pOld))/256,
                                     GetBlue (*pOld) + GetAlpha(*pNew)*(GetBlue (New) - GetBlue (*pOld))/256 );
            }
            else
                *pOld = MakeColor16( GetRed  (*pOld) + GetAlpha(*pNew)*(GetRed  (*pNew) - GetRed  (*pOld))/256,
                                     GetGreen(*pOld) + GetAlpha(*pNew)*(GetGreen(*pNew) - GetGreen(*pOld))/256,
                                     GetBlue (*pOld) + GetAlpha(*pNew)*(GetBlue (*pNew) - GetBlue (*pOld))/256 );
            pOld++;
            if( pInfo->horz_invert )
                pNew--;
            else
                pNew++;
        }

        pOld += screenW - Size.x;
        if( pInfo->horz_invert )
            pNew += pNewImage->size.x + Size.x;
        else
            pNew += pNewImage->size.x - Size.x;
    }
    return 0;
}
Не могу найти место где можно упростить вычисления или заменить логику. Пытался также сделать многопоточность с помощью openMP, но пока не ничего не получается да и это сильно не поможет, т.к. ядро 2,4 ггц не должно нагружаться на 100%...
Можно вместо "/256" написать ">> 8", может компилятор сам не оптимизирует. И ещё я бы не стал использовать методы для обращения к пикселям в таком низкоуровневом процессе.

Да и класс для цвета зря используется.

Короче, слишком высокоуровневый код, как по мне, неуместный для такого процесса.
Сложно сказать, но по виду - возможно, тормозит функция MakeColor16 и её вызов. Зачем там одни и те же касты выполняются дважды?
Да и само решение какое-то корявое - каждый пиксель менять. Хотя других я и не знаю.

Попробуй закомментить вызовы этой функции и посмотреть - меньше нагрузка стала?
Code:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
rhis->DoubleBuffered=true;
}
Code:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        ammo = new Graphics::TBitmap;
        ammo->LoadFromFile("ammo.bmp");
Form1->Canvas->Brush->Color=(TColor)RGB(0,0,0);
       Form1->Canvas->Rectangle(0,0,ClientWidth,ClientWidth);
/*Много кода и отрисовок*/
   delete ammo;
}

Quote:Это одна и та же запись.
Угу, но вдруг глючит) лучше уж проверить.

http://zalil.ru/33150201
Вот на всякий случай - прошу в код даже не вглядываться) данный сорс только чтобы показать как мерцает.
(28.04.2012 13:56)Sav Wrote: [ -> ]Можно вместо "/256" написать ">> 8", может компилятор сам не оптимизирует. И ещё я бы не стал использовать методы для обращения к пикселям в таком низкоуровневом процессе.

Да и класс для цвета зря используется.

Короче, слишком высокоуровневый код, как по мне, неуместный для такого процесса.
Я просто не думаю, что перевод всего на низкий уровень существенно повысит скорость. Дело не в сложности расчетов, а в их количестве. Вот если бы перенести эти расчеты на графический процессор или придумать другую логику.
А что значит >>? Просто я не в одном языке нормально не шарю.
(28.04.2012 14:04)Efrit Wrote: [ -> ]Попробуй закомментить вызовы этой функции и посмотреть - меньше нагрузка стала?
Я это и написал, просто привел всю функцию для наглядности.

Может ещё есть в какой-нибудь libpng уже готовая функция для наложения альфа канала?
Хотел ещё новые библиотеки zlib и libpng в GCC пропихнуть, но у них изменился синтаксис, а править у меня мозгов пока не хватит, просто думал тоже мож чего там оптимизировали.
Может вообще через openGL попробовать?
Quote:(кстати, нафига?)
Иначе следы будут. Ужасные)
Если не трудно, помести в комметарий эту строчку ( Form1->Canvas->Rectangle(0,0,ClientWidth,ClientWidth); ), и увидишь)
Упростил чуть чуть:
Code:
for( int y = 0; y < Size.y; y++ )
    {
        for( int x = 0; x < Size.x; x++ )
        {
            
            ro1 = GetRed  (*pOld);
            rn1 = GetRed  (*pNew);
            go1 = GetGreen  (*pOld);
            gn1 = GetGreen  (*pNew);
            bo1 = GetBlue  (*pOld);
            bn1 = GetBlue  (*pNew);
            an1 = GetAlpha(*pNew);
            if( ( *pNew & 0xFFFFFF ) == 0xFFFF ) // color for replacement
                        {
                color16 New = pInfo->color;
                if( New )
                *pOld = MakeColor16( GetRed  (*pOld) + GetAlpha(*pNew)*(GetRed  (New) - GetRed  (*pOld))/256,
                                     GetGreen(*pOld) + GetAlpha(*pNew)*(GetGreen(New) - GetGreen(*pOld))/256,
                                     GetBlue (*pOld) + GetAlpha(*pNew)*(GetBlue (New) - GetBlue (*pOld))/256 );
            }
            else
            {
            NewRed = ro1 + an1*(rn1 - ro1)/256;
            NewGreen = go1 + an1*(gn1 - go1)/256;
            NewBlue = bo1 + an1*(bn1 - bo1)/256;
                *pOld = MakeColor16( NewRed, NewGreen, NewBlue);
            }
            pOld++;
            if( pInfo->horz_invert )
                pNew--;
            else
                pNew++;
        }
Производительность выросла как минимум в 2 раза Dance3 по сему несказанно счастлив 109. Может что еще придумаю.
totkotoriy Wrote:Я просто не думаю, что перевод всего на низкий уровень существенно повысит скорость. Дело не в сложности расчетов, а в их количестве.
В героях делаются аналогичные вещи и ничего. Ну, дело твоё, но если не попробуешь сделать хоть что-то - точно ничего не получится.

>> - это поразрядный двоичный сдвиг вправо.

Вот видишь, такая фигня - а какой эффект. Sm Так что упростить как раз и надо.
packa, ну это же жуть! Unsure Плз, переформатируй свой код - читать же абсолютно невозможно. Я в Notepad++ открывал, есичо.
Да и зачем нам весь проект? Нужен лишь исходник, а ещё лучше - его фрагмент...

totkotoriy, ещё и в строчках типа *pOld = MakeColor16( GetRed (*pOld) + GetAlpha(*pNew)*(GetRed (New) - GetRed (*pOld))/256, тоже не помешало бы произвести замену на ro1, rn1 и иже с ними.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
Reference URL's