Помогите перевести маленький блок C++ в ASM

Тема в разделе "WASM.ASSEMBLER", создана пользователем vovka86, 17 июл 2008.

  1. vovka86

    vovka86 New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    2
    Добрый вечер,

    У меня есть функция на Visual C++ (не Managed C++) и в ней мне очень очень нужно оптимизировать один участок кода. Выход только один, переписать цикл под Ассемблер с использованием MMX. Но так как я мало знаю этот ассемблер, то прошу помогите пажалуйста, мне это очень нужно. Необходимый участок я выделил, от "[Begin Asm]" до "[End Asm]". Платформа win32, компилятор Visual C++ 2005. Очень буду благодарен за любую помощь.

    Код (Text):
    1. OLECONTAINER(void)::Draw(HDC hdcDraw, const RECT *rcDraw, BOOL bErase)
    2. {
    3.     HWND hwnd = GetHWND();
    4.     HRESULT hr;
    5.     RECT r;
    6.  
    7.     IOleObject *lpO = m_lpO;
    8.     IViewObject *lpV = m_lpViewObjectEx ? (IViewObject *)m_lpViewObjectEx : m_lpViewObject;
    9.  
    10.     if (!m_bTransparent)
    11.     {
    12.         RECT rTotal;
    13.             ::GetClientRect(hwnd, &rTotal);
    14.         if (lpV)
    15.         {
    16.             if (!hdcDraw)
    17.             {
    18.                 hdcDraw = ::GetDC(hwnd);
    19.                 hr = OleDraw(lpV, DVASPECT_CONTENT, hdcDraw, &rTotal);
    20.                 ::ReleaseDC(hwnd, hdcDraw);
    21.             }
    22.             else
    23.             {
    24.                 hr = OleDraw(lpV, DVASPECT_CONTENT, hdcDraw, &rTotal);
    25.             }
    26.         }
    27.         return;
    28.     }
    29.  
    30.     ::GetWindowRect(hwnd, &r);
    31.     if (!m_hdcBack || !EqualRect(&r, &m_rcBounds))
    32.     {
    33.         if (m_hdcBack)
    34.             ::DeleteDC(m_hdcBack);
    35.         if (m_bmpBack)
    36.             ::DeleteObject(m_bmpBack);
    37.         if (m_hdcBackW)
    38.             ::DeleteDC(m_hdcBackW);
    39.         if (m_bmpBackW)
    40.             ::DeleteObject(m_bmpBackW);
    41.         m_rcBounds = r;
    42.         HDC hdc = ::GetDC(hwnd);
    43.         BITMAPINFOHEADER bih = {0};
    44.         bih.biSize = sizeof(BITMAPINFOHEADER);
    45.         bih.biBitCount = 32;
    46.         bih.biCompression = BI_RGB;
    47.         bih.biPlanes = 1;
    48.         bih.biWidth = r.right - r.left;
    49.         bih.biHeight = -(r.bottom - r.top);
    50.         m_hdcBack = CreateCompatibleDC(hdc);
    51.         m_bmpBack = CreateDIBSection(hdc, (BITMAPINFO *)&bih, DIB_RGB_COLORS, (void **)&m_lpBitsOnly, NULL, 0x0);
    52.         SelectObject(m_hdcBack, m_bmpBack);
    53.         if (m_bFixTransparency)
    54.         {
    55.             m_hdcBackW = CreateCompatibleDC(hdc);
    56.             m_bmpBackW = CreateDIBSection(hdc, (BITMAPINFO *)&bih, DIB_RGB_COLORS, (void **)&m_lpBitsOnlyW, NULL, 0x0);
    57.             SelectObject(m_hdcBackW, m_bmpBackW);
    58.         }
    59.         ::ReleaseDC(hwnd, hdc);
    60.         if (m_iBPP == 0)
    61.             m_iBPP = GetDeviceCaps(m_hdcBack, BITSPIXEL);
    62.     }
    63.     POINT p = {r.left, r.top};
    64.     POINT p2 = {0, 0};
    65.     SIZE sz = {r.right-r.left, r.bottom-r.top};
    66.  
    67.     if (lpO && lpV)
    68.     {
    69.         RECT rTotal;
    70.         ::GetClientRect(hwnd, &rTotal);
    71.         RECTL rcBounds = {rTotal.left, rTotal.top, rTotal.right, rTotal.bottom};
    72.         BYTE *dst = m_lpBitsOnly, *dstW;
    73.         if (m_iBPP == 32)
    74.         {
    75.             if (!m_bFixTransparency) //if flash player version is other than 8, do usual painting
    76.             {
    77.                 memset(m_lpBitsOnly, 0, sz.cx * sz.cy * 4);
    78.                 hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal);
    79.             }
    80.             else //if player version is 8, we need to fix flash player 8 control transparency bug
    81.             {
    82.                 memset(m_lpBitsOnly, 0, sz.cx * sz.cy * 4);
    83.                 memset(m_lpBitsOnlyW, 255, sz.cx * sz.cy * 4);
    84.                 hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal);
    85.                 hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBackW, &rTotal);
    86.                 dst = m_lpBitsOnly;
    87.                 dstW = m_lpBitsOnlyW;
    88.                 BYTE r, g, b, a, rw, gw, bw, aw, alpha_r, alpha_g, alpha_b, alpha;
    89.  
    90.                 // [BEGIN ASM]
    91.                 for (int y = 0; y < sz.cy; y++)
    92.                 {
    93.                     for (int x = 0; x < sz.cx; x++)
    94.                     {
    95.                         //the idea is that we draw the same data onto black and white DC's
    96.                         //and then calculate per pixel alpha based on difference, produced by alpha blending
    97.                         r = *dst++;
    98.                         g = *dst++;
    99.                         b = *dst++;
    100.                         a = *dst++;
    101.                         rw = *dstW++;
    102.                         gw = *dstW++;
    103.                         bw = *dstW++;
    104.                         aw = *dstW++;
    105.                         alpha_r = rw-r;
    106.                         alpha_g = gw-g;
    107.                         alpha_b = bw-b;
    108.                         //division by 3 is for accuracy and can be replaced by
    109.                         //alpha = alpha_g; for example
    110.                         alpha = (alpha_r + alpha_g + alpha_b) / 3;
    111.                         *(dst - 1) = 255 - alpha;
    112.                         //this algorithm should be optimized for MMX to achieve best performance
    113.                     }
    114.                 }
    115.                 // [END ASM]
    116.             }
    117.         }
    118.         else //in 8/16/24 bit screen depth UpdateLayeredWindow produces wrong results - we use underlaying DC to paint to
    119.         {
    120.             HWND hwndParent = ::GetParent(hwnd);
    121.             HDC hdcParent = ::GetWindowDC(hwndParent);
    122.             BOOL bRet = BitBlt(m_hdcBack, 0, 0, rTotal.right, rTotal.bottom, hdcParent, 0, 0, SRCCOPY);
    123.             ::ReleaseDC(hwndParent, hdcParent);
    124.             hr = OleDraw(lpV, DVASPECT_TRANSPARENT, m_hdcBack, &rTotal);
    125.             dst = m_lpBitsOnly;
    126.         }
    127.     }
    128.  
    129.     BLENDFUNCTION bf;
    130.     bf.BlendOp = AC_SRC_OVER;
    131.     bf.AlphaFormat = AC_SRC_ALPHA;
    132.     bf.BlendFlags = 0;
    133.     bf.SourceConstantAlpha = 255;
    134.     BOOL bRet = UpdateLayeredWindow(hwnd, NULL, &p, &sz, m_hdcBack, &p2, 0, &bf, m_iBPP == 32 ? ULW_ALPHA : ULW_OPAQUE);
    135. }
     
  2. vovka86

    vovka86 New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2008
    Сообщения:
    2
    Работа на час максимум. Оптимизированный код мне очень необходим, и готов первуму предлажившему заплатить 240 руб (10$) через систему PayPal. Пишите на email: vladimir [sobaka] telcobalt [to4ka] lv. Вышлю рабочий проект в Visual Studio 2005 для отладки. Код должен быть оптимизирован с помощью инструкции mmx, с проверкой поддерживает ли он их, если нет тогда использование стандартных инструкции.
     
  3. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    cl /Fa и с ключиками оптимизации поиграться
     
  4. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    а встроеный в студию ассемблер воабще mmx поддреживает?
     
  5. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    Вроде да. и не только MMX. еще помоему SSE, насчет SSE2 и т.д. точно не знаю