Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Pointer->Integer->Pointer


Страницы:   1 2 3 4 5

alertus ©   (2005-05-27 17:36:00) 

Подскажите, пожалуйста, если я пишу так:

a:^real;
p:^real;
....
getmem(a,100*sizeof(real));
p:=pointer(integer(a)+0);
p^:=0.347;
p:=pointer(integer(a)+8);
p^:=0.764;
p:=pointer(integer(a)+16);
p^:=0.764;
....


Похоже ли это на работу динамического массива и какова будет разница в скорости??


begin...end   (2005-05-30 20:39:00) [1]

> alertus ©   (27.05.05 21:02) [33]

Дополнение к [78]: матрицы должны быть расположены в памяти по строкам -- вначале первая строка, затем вторая и т.д. Матрица результата будет размещена таким же образом.


Defunct   (2005-05-30 20:08:00) [2]

> begin...end
Прошу прощения что поставил неверный коментарий:

{ подготовка MMX и SSE2 }


Defunct   (2005-05-30 20:07:00) [3]

begin...end ©   (30.05.05 20:05) [78]

Код под P4, mulsd на P3 нет.


begin...end   (2005-05-30 20:05:00) [4]

> alertus ©   (27.05.05 21:02) [33]

Этот код не выполняет умножения матриц. Вот рабочий код:

const
 M = 311; // Число строк в A и столбцов в B
 N = 700; // Число строк в B и столбцов в A
type
 TElement = Real;
 PElement = ^TElement;
var
 Temp: TElement;
 i, j, k: Integer;
 A, B, C: PElement;
 pA, pB, pC: PElement;
begin
 GetMem(A, M * N * sizeof(TElement));
 GetMem(B, N * M * sizeof(TElement));
 GetMem(C, M * M * sizeof(TElement));
 try
   pC := C;
   for i := 1 to M do
   begin
     pA := PElement(Integer(A) + (i - 1) * N * sizeof(TElement));
     for j := 1 to M do
     begin
       pB := PElement(Integer(B) + (j - 1) * sizeof(TElement));
       Temp := 0;
       for k := 1 to N do
       begin
         Temp := Temp + pA^ * pB^;
         Inc(pA);
         Inc(pB, M)
       end;
       pC^ := Temp;
       Inc(pC);
       Dec(pA, N)
     end
   end
 finally
   FreeMem(A);
   FreeMem(B);
   FreeMem(C)
 end
end.


> Defunct ©   (29.05.05 07:54) [69]
> Defunct ©   (29.05.05 08:31) [70]

Нерабочий код. Вылетает с External Exception.


DiamondShark   (2005-05-30 17:53:00) [5]


> зависит ли скорость от расстояния между этими физическими
> адресами??

В системах с многоуровневой памятью -- зависит.
Иногда очень сильно.


Defunct   (2005-05-30 17:28:00) [6]

alertus ©   (30.05.05 17:06) [74]

Боюсь у Athlon'a нет SSE. (во всяком случае насколько я помню у Athlon TB не было, а вы говорили что у вас Athlon 800, это скорее всего и есть TB). У AMD процессоров есть 3DNow! для работы с числами с плавающей точкой, так что ищите мануал на сайте AMD а не Intel'а. Вам всего навсего нужна замена команд ADDPD/ADDSD и MULPD/MULSD.


Digitman   (2005-05-30 17:11:00) [7]

на сайте у Анатолия Подгорецкого, кажется, был ..

в оригинале файл называется 24547112.pdf

IA-32 Intel ® Architecture
Software Developer’s
Manual
Volume 2 :
Instruction Set Reference


alertus   (2005-05-30 17:06:00) [8]

Как я понял, там почти тоже самое, как программирование на асме, только добавляются регистры новые для быстрых операций с вещественными числами??
А ссылку не подскажете??


Digitman   (2005-05-30 17:03:00) [9]


> Подскажите, пожелуйста, где можно прочитать про инструкции
> SSE??


в мануалах от Интела ... это же его детище ..


alertus   (2005-05-30 17:00:00) [10]

Подскажите, пожелуйста, где можно прочитать про инструкции SSE??


Marser   (2005-05-29 11:03:00) [11]


> begin...end ©
> Defunct ©  

Break!
Вы уже давно грызётесь. А толку-то? Никому из вас это на пользу не идёт, авторитету не добавляет. Только однеому создаёт неповторимый оттенок, а другому ещё более его усугубляет.
Зачем?


Defunct   (2005-05-29 08:31:00) [12]

Кстати именно этот множитель индекса и не учтен в [33] его вообще там нет, соответственно функция [33] не рабочая .. и моя не рабочая (т.к. делал по образу [33]), а чтобы сделать ее рабочей надо поменять в цикле k этот код

 movd   eax, mm0   ; // pointer to B
 add    eax, ebx   ;
 movd   esi, mm4
 movq   xmm0, [eax + esi*8]
 movd   eax, mm1   ; // pointer to A
 add    eax, ebx
 movd   esi, mm3


на такой:

 movd   eax, mm0   ; // pointer to B
 movd   esi, mm4
 add    esi, ebx   ;
 movq   xmm0, [eax + esi*8]
 movd   eax, mm1   ; // pointer to A
 movd   esi, mm3
 add    esi, ebx


Defunct   (2005-05-29 07:54:00) [13]

TUser ©   (29.05.05 05:01) [68]

навеяно вашими размышлениями..
Алгоритм [33] на асме с MMX и SSE и масштабированием индексов о котором здесь был спор с begin...end.

Работает почти в 3 раза быстрее чем [33]. 0.38 сек. (моя функция) против 1.0сек. (оригинал [33])

procedure TForm2.Button4Click(Sender: TObject);
var
a:^real;  //311x700
b:^real;  //700x311
c:^real;  //311x311
begin
getmem(a,311*700*sizeof(real));
getmem(b,311*700*sizeof(real));
getmem(c,311*311*sizeof(real));

memo1.lines.add(writems);

{}
asm
{ подготовка MMX и SSE }
  push  ebx
  push  esi

  mov   eax, c
  movd  mm6, eax
  mov   eax, b
  movd  mm0, eax
  mov   eax, a
  movd  mm1, eax      // A - low dword

  mov   eax, 311
  movd  mm2, eax
  punpckldq mm2, mm2  // Двойной множитель на 311

// for i := 0 to 310 do
  mov   ecx, 310
@L1:
// for j := 0 to 310 do
  mov   edx, 310
@L2:
  pxor  xmm1, xmm1    // Переменная Temp в фантазии SSE
                      // Расчет i/j адреса вынесен из цикла k
  movd  mm4, ecx
  punpckldq mm4, mm4
  movd  mm4, edx
  movq  mm3, mm4
  pmullw mm3, mm2
  pmulhw mm4, mm2
  pslld  mm4, 16      // j * 311
  paddd  mm4, mm3
  punpckldq mm3, mm4  // i * 311

// for k := 0 to 699 do
  mov   ebx, 699
@L3:

  movd   eax, mm0   ; // pointer to B
  add    eax, ebx   ;
  movd   esi, mm4
  movq   xmm0, [eax + esi*8]
  movd   eax, mm1   ; // pointer to A
  add    eax, ebx
  movd   esi, mm3
  mulsd  xmm0, [eax + esi*8]
  addpd  xmm1, xmm0          ; // temp:=temp+pa^*pb^;

  dec    ebx
  jns    @L3

  movd   eax, mm6   ; // pointer to C
  movd   esi, mm4   ; // j * 311
  add    esi, ecx   ; // + i
  movq   [eax + esi*8], xmm1 // сохраняем temp

  dec    edx
  jns    @L2

  dec    ecx
  jns    @L1

  emms
  pop  esi
  pop  ebx
end;

memo1.lines.add(writems);

end;


TUser   (2005-05-29 05:01:00) [14]

> Если на асме есть возможность расчитать индекс быстрее,
почему бы не воспользоваться этим?

Да я не против. Просто быстрее в таком случае означает - процентов на 10 максимум, я понимаю. Обычно, если уж программа медленно работает, то очень сильно помогает изменение логики работы алгоритма, а не переход на си, ассемблер или покупка супер-компьютера. А судя по [10] тут как раз такой случай, что алгоритм можно улучшить.

Хотя против асма тоже ничего не имею.


Defunct   (2005-05-28 21:01:00) [15]

begin...end ©   (28.05.05 20:31) [66]

> Если это так, то [31] и [36] можно объяснить только корявостью написанного Вами теста.

Странно, почему же у меня "коряво написанный тест" это подтверждает.

А может быть ваше "неламерское" видоизменение, так повлияло. Не вы ли написали:
> Ваш код я видоизменил: вместо ламерского способа измерения времени

> Верно, Вы больше похожи на дошкольника.
>> выслушивать все это дерьмо
> Придётся.

LMD


begin...end   (2005-05-28 20:31:00) [16]

> Defunct ©   (28.05.05 18:59) [65]

> LMD

Из этой реплики следует, что Вам надоело жить.

>> Судя по тому, как Вы были уверены в результате,
> Я до сих пор в нем уверен.

А я до сих пор уверен в результатах [31] и [36].

> Defunct ©   (28.05.05 18:59) [65]

Если это так, то [31] и [36] можно объяснить только корявостью написанного Вами теста.

> я тебе не школьник

Верно, Вы больше похожи на дошкольника.

> выслушивать все это дерьмо

Придётся.

Продолжать разговаривать с деревом смысла не вижу.


Defunct   (2005-05-28 18:59:00) [17]

Прочитать о масштабировании индексных региcтров можно в "Instruction Set Reference Vol 2.A" в разделе 2.6 "Addressing-Mode Enconiding of ModR/M and SIB"

В "Vol 2.B, Appendix B" можно найти что инструкции
[ecx]
[ecx*8]
выполняются за одинаковое количество тактов.

Всего хорошего.

PS: (как меня уже дастали выбрыки begin...end, я тебе не школьник, чтобы от тебя выслушивать все это дерьмо).


Defunct   (2005-05-28 18:03:00) [18]

begin...end ©   (28.05.05 10:55) [61]
LMD

> Судя по тому, как Вы были уверены в результате,
Я до сих пор в нем уверен.


Sergey Masloff   (28.05.05 11:28) [62]
прочитайте ветку дальше.

TUser ©   (28.05.05 13:11) [63]
Если на асме есть возможность расчитать индекс быстрее, почему бы не воспользоваться этим?


TUser   (2005-05-28 13:11:00) [19]

Вообще, не думаю, что тут надо браться за асм или изменять логику работы с дин.массивами. Сущействует несколько алгоритмов умножения матриц, который различаются скоростью работы. Посмотрите в интернете по словам 'алгоритм Штрассена' - это один из самых быстрых.


Sergey Masloff   (2005-05-28 11:28:00) [20]

begin...end ©   (27.05.05 20:58) [31]
>способа измерения времени выполнения кода функцией использовал >GetTickCount, хотя это тоже не лучший способ.
Ну да. Это ж время работы системы а не вашего кода. Так что GetThreadTimes() было бы уместнее (если конечно это в NT системе происходит). А иначе меряется средняя по больнице температура.


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо