Выделение выровненного участка памяти

Тема в разделе "WASM.BEGINNERS", создана пользователем Xerx, 3 янв 2008.

  1. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    С Наступившим!
    Подскажите, можно ли как-нибудь выделить память под Win32 сразу с необходимым выравниванием? (на 4 или 16 байт).
    В голову приходит только выделять на 15 байт больше (для выравнивания на 16), а затем уже корректировать смещение для реального начала буфера.
    Может все-таки есть способ получше?
     
  2. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    VirtualAlloc() / HeapAlloc() - выделяют память начиная с адреса, выровненного на 0x1000
    т.е. и 4 и 0x10 включительно. С выравниванием не парься )))))
     
  3. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Magnum
    Просто мне нужно копировать достаточно большие блоки (~1МБ в обычном состоянии). Причем очень быстро и часто.
    Вот и хотел выделять память с выравниванием для нормальной работы.

    Great
    Буду пробовать VirtualAlloc.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    VirtualAlloc однозначно.

    Ээ а хип аллок то с какой радости? Если я выделяю в куче допустим 20 байт. Или ты про то, если размер выделения кратен странице?

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

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    P.S. Вопрос не совсем по теме, но не хочу засорять форум лишними ветками.
    Вот код копирования блока памяти из src в dst длиной в u32Len байт на MMX.
    Большинство вызовов - для блоков в пределах 1МБ с размером кратным 4 или даже 16.
    Можно его как-нибудь ускорить/оптимизировать/доработать? (разговор ТОЛЬКО о MMX)

    Код (Text):
    1. void copyMemoryMMX( VU8 src, VU8 dst, U32 u32Len ) {
    2.     if (!u32Len) return;
    3.    
    4.     // тут сохраняю MMX регистры
    5.     DWORD tmp[2*8];
    6.    
    7.     __asm {
    8.         pushad
    9.        
    10.         mov     esi,    src
    11.         mov     edi,    dst
    12.        
    13.         mov     eax,    u32Len
    14.        
    15.         // может стоит вставить здесь проверку на < 64 и просто rep movsb?
    16.        
    17.         mov     edx,    64 // приращение
    18.        
    19.         mov     ecx,    eax
    20.         shr     ecx,    6
    21.         and     eax,    63
    22.        
    23.         // сохраняю MMX регистры
    24.         movq    qword ptr [tmp],    mm0
    25.         movq    qword ptr [tmp+8],  mm1
    26.         movq    qword ptr [tmp+16], mm2
    27.         movq    qword ptr [tmp+24], mm3
    28.         movq    qword ptr [tmp+32], mm4
    29.         movq    qword ptr [tmp+40], mm5
    30.         movq    qword ptr [tmp+48], mm6
    31.         movq    qword ptr [tmp+56], mm7
    32.        
    33.         test    ecx,    ecx
    34.         jz      _Below64
    35.             // цикл копирования по 64 байта
    36.             _copy_loop_64:
    37.                 movq    mm0,    qword ptr [esi]
    38.                 movq    mm1,    qword ptr [esi+8]
    39.                 movq    mm2,    qword ptr [esi+16]
    40.                 movq    mm3,    qword ptr [esi+24]
    41.                 movq    mm4,    qword ptr [esi+32]
    42.                 movq    mm5,    qword ptr [esi+40]
    43.                 movq    mm6,    qword ptr [esi+48]
    44.                 movq    mm7,    qword ptr [esi+56]
    45.                
    46.                 movq    qword ptr [edi],    mm0
    47.                 movq    qword ptr [edi+8],  mm1
    48.                 movq    qword ptr [edi+16], mm2
    49.                 movq    qword ptr [edi+24], mm3
    50.                 movq    qword ptr [edi+32], mm4
    51.                 movq    qword ptr [edi+40], mm5
    52.                 movq    qword ptr [edi+48], mm6
    53.                 movq    qword ptr [edi+56], mm7
    54.                
    55.                 add     esi,    edx
    56.                 add     edi,    edx
    57.                 dec     ecx
    58.                 jnz     _copy_loop_64
    59.        
    60.     _Below64:
    61.         // меньше 64 байт. длина в EAX. в ECX содержится 0.
    62.         shr     edx,    1 // edx == 32
    63.        
    64.         cmp     eax,    edx
    65.         jb      _Below32
    66.             // больше 32 но меньше 64 байт - можно скопировать еще 32
    67.                 movq    mm0,    qword ptr [esi]
    68.                 movq    mm1,    qword ptr [esi+8]
    69.                 movq    mm2,    qword ptr [esi+16]
    70.                 movq    mm3,    qword ptr [esi+24]
    71.                
    72.                 movq    qword ptr [edi],    mm0
    73.                 movq    qword ptr [edi+8],  mm1
    74.                 movq    qword ptr [edi+16], mm2
    75.                 movq    qword ptr [edi+24], mm3
    76.                
    77.                 add     esi,    edx
    78.                 add     edi,    edx
    79.                 sub     eax,    edx
    80.        
    81.     _Below32:
    82.         // меньше 32 байт
    83.         shr     edx,    1 // edx == 16
    84.        
    85.         cmp     eax,    edx
    86.         jb      _Below16
    87.             // больше 16 но меньше 32 байт - можно скопировать еще 16
    88.                 movq    mm0,    qword ptr [esi]
    89.                 movq    mm1,    qword ptr [esi+8]
    90.                
    91.                 movq    qword ptr [edi],    mm0
    92.                 movq    qword ptr [edi+8],  mm1
    93.                
    94.                 add     esi,    edx
    95.                 add     edi,    edx
    96.                 sub     eax,    edx
    97.            
    98.     _Below16:
    99.         // меньше 16 байт
    100.         shr     edx,    1 // edx == 16
    101.        
    102.         cmp     eax,    edx
    103.         jb      _Below8
    104.             // больше 8 но меньше 16 байт - можно скопировать еще 8
    105.                 movq    mm0,    qword ptr [esi]
    106.                
    107.                 movq    qword ptr [edi],    mm0
    108.                
    109.                 add     esi,    edx
    110.                 add     edi,    edx
    111.                 sub     eax,    edx
    112.                
    113.     _Below8:
    114.         // меньше 8 байт. не буду извращаться - просто rep movsb
    115.         test    eax,    eax
    116.         jz      _zero
    117.             xchg    eax,    ecx
    118.             cld
    119.             rep movsb
    120.        
    121.     _zero:
    122.        
    123.         // восстанавливаю MMX регистры
    124.         movq    mm0,    qword ptr [tmp]
    125.         movq    mm1,    qword ptr [tmp+8]
    126.         movq    mm2,    qword ptr [tmp+16]
    127.         movq    mm3,    qword ptr [tmp+24]
    128.         movq    mm4,    qword ptr [tmp+32]
    129.         movq    mm5,    qword ptr [tmp+40]
    130.         movq    mm6,    qword ptr [tmp+48]
    131.         movq    mm7,    qword ptr [tmp+56]
    132.        
    133.         popad
    134.     }
    135. }
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
  7. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    IceStudent
    Как раз то, что надо! Я нашел урезанный вариант Block prefetch paper и по нему и сделал... Но еще можно сильно улучшить.
    Спасибо большое!
     
  8. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon