Есть большой кусок памяти (относительно), у меня в тесте - 600*600*4 байт
Нужно его максимально быстро очистить.
сначала попробовал memset
memset(backBuffer->getBuffer( )->getDataPtr( ), 0x00, backBuffer->getBuffer( )->getDataSize( ));
и получил 700 FPS, что маловато : \
потом попробовал по-велосипедить:
int clearColor = 0xffff0000; int bbPixCnt = backBuffer->width * backBuffer->height; if(IsEvenNum( bbPixCnt)) { __int64* bbPtr = static_cast<__int64*>( backBuffer->getBuffer( )->getDataPtr( )); __int64 clearVal = static_cast<__int64>( clearColor) & 0xffffffff; clearVal = clearVal | ( clearVal << 32); int numLoops = bbPixCnt / 2; for( int i = 0; i < numLoops; i++) bbPtr[i] = clearVal; } else { int* bbPtr = reinterpret_cast<int*>( backBuffer->getBuffer( )->getDataPtr( )); for( int i = 0; i < bbPixCnt; i++) bbPtr[i] = 0; }
и получил примерно такой-же FPS. Однако, помнится, даже на C# это дело у меня работало на 1200 ФПС ! О___О
Вопрос - как сиё ускорить? Да ещё чтобы можно было задавать цвет оцистки (цвет всегда формата int)
for(int i = 0; i < numLoops; i++) bbPtr[i] = clearVal;
попробуй заменить на
bbPtr[0] = clearVal; for(int i = 1; i < numLoops; i++) bbPtr[i] = bbPtr[i-1];
Или попробуй по аналогии заменить memset на memmove
Пара идей:
1) За одну иттерацию заменять N значений
2) Использовать SIMD инструкции, QWORD'ы
XProger
> 1) За одну иттерацию заменять N значений
так и сделал, впринципе. Надо попробовать с 4 и 8
XProger
> 2) Использовать SIMD инструкции, QWORD'ы
не, нужно без них )
.L
> __int64
Смысл? Приложение 64х битное? Если нет, то используются 32х битные регистры
Плюсую к SIMD.
Что-то полезное: http://www.gamedev.ru/code/forum/?id=141842
вот сделал заполнение 8 значений:
struct int256 { int r0; int r1; int r2; int r3; int r4; int r5; int r6; int r7; }; void clear() { int clearColor = 0xffff0000; int bbPixCnt = backBuffer->width * backBuffer->height; if( !( bbPixCnt % 8)) { int256 clearVal = {clearColor,clearColor,clearColor,clearColor,clearColor,clearColor,clearColor,clearColor}; int256* bbPtr = reinterpret_cast<int256*>( backBuffer->getBuffer( )->getDataPtr( )); int numLoops = bbPixCnt >> 3; bbPtr[0] = clearVal; for( int i = 1; i < numLoops; i++) bbPtr[i] = bbPtr[i - 1]; } ......
и фпс вообще ни как не поднялся : \
Blew_zc
> Смысл?
писать 8 байт за раз?
.L
Тут надо на ассемблер смотреть, что лишнего пишется. Так же убедись, что все действующие лица - локальные переменные.
.L
> писать 8 байт за раз?
Кто тебе сказал что оно за раз пишется? Посмотри в асм и удивишься. Будет тот же результат, что в самом начале у тебя был...
А SSE2 тебе даст распараллеленные инструкции, которые еще и по 16 байт сразу пишут.
.L
Зачем делать buf[k] = buf[k-1]? Какой тут профит, кроме лишнего чтения из памяти.
обычный цикл, или чуть-чуть развернуть руками:
for (k = 0; k < size; k += 4)
{
a[k] = N;
a[k+1] = N;
a[k+2] = N;
a[k+3] = N;
}
так не пробовал?
>>Как быстрее очистить большой кусок памяти?
Взять новый кусок, заранее выделеный и почищеный :-D
Ну а если серьезно, то надо хотя-бы mmx заюзать, иначе получишь тот же memset :)
.L
> Есть большой кусок памяти (относительно), у меня в тесте - 600*600*4 байт
> Нужно его максимально быстро очистить.
> это дело у меня работало на 1200 ФПС !
Очень странно слышать от тебя такие слова.
Реализация: memset . Быстрее не сделаешь. Быстрота у неё внутри. Создавали её не дураки.
До чего ж у нас любят страдать уйнёй.
.L
ksacvet777
> Реализация: memset . Быстрее не сделаешь. Быстрота у неё внутри. Создавали её
> не дураки.
какие твои доказательства? ты мерял, или так, языком почесать?
ksacvet777
> Реализация: memset . Быстрее не сделаешь. Быстрота у неё внутри. Создавали её
> не дураки.
сравни memset и заполнение по mmx\sse
memset от Intel C++ Compiler
Тема в архиве.