Копирование данных в буфер DirectX

Тема в разделе "WASM.DirectX", создана пользователем PavDimka, 22 сен 2010.

  1. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    Всем привет.
    В Delphi есть процедура Move( const Source; var Dest; count : Integer );
    обычно с её помощью копируют данные в буфер вершин.
    На всякий случай привожу её код:
    Код (Text):
    1. asm
    2. {     ->EAX     Pointer to source       }
    3. {       EDX     Pointer to destination  }
    4. {       ECX     Count                   }
    5.  
    6.         PUSH    ESI
    7.         PUSH    EDI
    8.  
    9.         MOV     ESI,EAX
    10.         MOV     EDI,EDX
    11.  
    12.         MOV     EAX,ECX
    13.  
    14.         CMP     EDI,ESI
    15.         JA      @@down
    16.         JE      @@exit
    17.  
    18.         SAR     ECX,2           { copy count DIV 4 dwords       }
    19.         JS      @@exit
    20.  
    21.         REP     MOVSD
    22.  
    23.         MOV     ECX,EAX
    24.         AND     ECX,03H
    25.         REP     MOVSB           { copy count MOD 4 bytes        }
    26.         JMP     @@exit
    27.  
    28. @@down:
    29.         LEA     ESI,[ESI+ECX-4] { point ESI to last dword of source     }
    30.         LEA     EDI,[EDI+ECX-4] { point EDI to last dword of dest       }
    31.  
    32.         SAR     ECX,2           { copy count DIV 4 dwords       }
    33.         JS      @@exit
    34.         STD
    35.         REP     MOVSD
    36.  
    37.         MOV     ECX,EAX
    38.         AND     ECX,03H         { copy count MOD 4 bytes        }
    39.         ADD     ESI,4-1         { point to last byte of rest    }
    40.         ADD     EDI,4-1
    41.         REP     MOVSB
    42.         CLD
    43. @@exit:
    44.         POP     EDI
    45.         POP     ESI
    46. end;
    Будьте любезны и скажите, если я буду использовать вместо этой процедуры цикл:
    Код (Text):
    1. for i: 100 downto 0 do
    2. begin
    3.  VertexPointer(A)^ := Vertex[i];
    4.  Inc(Cardinal(A), VertexSize);
    5. end;
    На сколько сильно я проиграю в скорости записи данных в видеопамять?

    Дело в том, что мне нужно организовать доступ ко всему залоченному буферу, но поменять нужно лишь некоторое число вершин, но время от времени буфер может быть полностью переписан.
    Вот собственном мой код для записи данных в буфер. Можно ли его усовершенствовать, чтоб он был быстрее и какие способы для этого существуют.
    Код (Text):
    1. procedure TBufferMemory.SetItemValue(Y, X: Uint32; const Value: Pointer);
    2. begin
    3.   if FFirstAllocatedElement = nil then
    4.     Exit;
    5.   if not(Y = FRowNumberInMatrix) then
    6.   begin { Если необходимо сделать сдвиг строки элементов }
    7.     FRowNumberInMatrix := Y;
    8.     FHorisontalPointer := FFirstAllocatedElement;
    9.     inc(Uint32(FHorisontalPointer), Y * FSizeOfHorisontalLine);
    10.     FVerticalPointer := FHorisontalPointer;
    11.     FColumnNumberInMatrix := 0;
    12.   end;
    13.   if X = FColumnNumberInMatrix + 1 then
    14.   begin { Записать данные в следующую ячейку памяти }
    15.     inc(FColumnNumberInMatrix);
    16.     inc(Uint32(FVerticalPointer), FSizeOfOneElement);
    17.   end
    18.   else if X = FColumnNumberInMatrix - 1 then
    19.   begin { Записать данные в предыдущую ячейку памяти }
    20.     dec(FColumnNumberInMatrix);
    21.     dec(Uint32(FVerticalPointer), FSizeOfOneElement);
    22.   end
    23.   else if not(X = FColumnNumberInMatrix) then
    24.   begin { Записать данные в произвольную ячейку отличную от предыдущей }
    25.     FColumnNumberInMatrix := X;
    26.     FVerticalPointer := FHorisontalPointer;
    27.     inc(Uint32(FVerticalPointer), X * FSizeOfOneElement);
    28.   end;
    29.   Move(Value^, FVerticalPointer^, FSizeOfOneElement);
    30. end;
     
  2. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    35 человек смотрели тему и ни одного комментария.
    У меня сложилось такое впечатление: или я неправильно задал вопросы или у прочитавших нет ответов.
     
  3. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    просто вопрос такой.
    сделайте бенч того и того и будете знать точно.
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    PavDimka
    Ещё тут мало дельфистов, соответсвенно мне например это и скомпилить нечем чтобы глянуть подробности и вникать в такой код лень.
    Поэтому могу только посоветовать применить rdtst для сравнительных замеров, поищи по форуму это тут часто обсуждалось.
     
  5. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    Сделал тест на 1000 проходов. В среднем полное копирование в цикле на 30-35 % медленнее. Помогите мне хоть чуть-чуть разогнать мою процедуру SetItemValue. Существует ли такой способ написания процедуры на asm, чтоб она работала быстрее, чем после обработки её дельфийским компилятором?
     
  6. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    А почему вы думаете что вы пишете непосредственно в видеопамять?
    Не указано что за буфер, вижу только просто кусок памяти в который пытаетесь произвольно записать что-то.

    существует, только смотря что под этим подразумевать. Если замена кучи специфических дельфовых функов десятком mmx команд, то выигрыш будет заметен. Если теже самые простые функции пытататься написать теми же командами ассемблера, в чем тогда смысл?
     
  7. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    Указатель получен при использовании функции Lock в IDirect3DvertexBuffer9. я конечно получаю указатель не на видеостраницу, но на участок видеопамяти под данные для вершин. По крайней мере, если используется аппаратная поддержка при инициализации девайса это должно быть правдой.
    Хочу чтоб выигрыш стал заметным, но писать на asm не умею, но чуть-чуть понимаю.
     
  8. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    напишите весь нужный кусок на С (без ++), скомпильте интел С. поиграйтесь с флагами. если вы будете выжимать на асме не зная последнего - будет только хуже.
     
  9. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    и еще одно - переход в функцию это много тактов. если вы выжимаете, то надо уменьшать количество переходов и вызовов и количество переменных. это в общем случае. нюансов тут хватает.
    скорей всего даже у вас провал не в этом месте. сколько вы вершин копируете? так много, что аж комп тормозит? а сколько оно отрисовываться тогда должно?
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    PavDimka
    Можно по-русски, что Вы хотите?
     
  11. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    Спасибо за совет. Тут дело не в количестве и тормозах, а в задаче.
    Мне нужно организовать доступ к отдельным элементам буфера вершин. В тот момент, когда буфер заблокирован, а в нём уже содержатся данные, нужно поменять некоторые вершины. Сейчас это реализовано в коде SetItemValue. Источником данных служит таблица с вершинами [0,0,xmax,ymax]. Из таблицы берется указатель на вершину заданного размера из строки Y, колонки X и копируется в буфер вершин.
    Внутри процедуры реализован механизм перехода от начала буфера вершин до начала координат вершин из строки Y. Начало строки Y = размер вершины * номер строки + начало данных. Потом производится переход к вершине из колонки X. Координата вершины = Начало строки Y + размер вершины + X.
    Запись и выход.
    Алгоритм содержит проверки: есль ли переход к новой строке? Новая координата X меньше или больше на единицу предыдущей координаты? Это специальные случаи.
     
  12. PavDimka

    PavDimka New Member

    Публикаций:
    0
    Регистрация:
    6 мар 2010
    Сообщения:
    6
    Ого! Как забавно, порой вспомнить о том, какие вопросы задавались месяц назад.
    Задача оптимизации алгоритма визуализации потока данных решена и протестирована.
    Общее увеличение производительности составляет порядка 10 %.
    Пропускная способность мультимедиа потока в формате 2D для графического интерфейса Direct3D9 возросла почти в 3 раза, однако, для ряда задач по визуализации тригонометрических функций и иных линейных уравнений увеличилась в 25 раз. Возможен вывод сложных двумерных графов с множественной зависимостью при частоте обновления приближенной к частоте регенерации экрана.
    Кто-нибудь знает, как правильно лицензировать программный код?