Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 08:53
Оценка: 15 (1)
    for(unsigned int l=0; l<size*size; l++)
    {
        marks[l] = klas.yel[l]; <--- memcpy?
        data[l] = 99999;        <--- ?
    }
Re[4]: Как из этого выжать максимальную скорость?
От: Net Cognition  
Дата: 17.08.05 09:42
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.

J>
J>for (int *p = data+size*size; p!=data; *(--p) = 99999);  
J>


Можно приминить еще, разворачивание цикла.
Re[4]: Как из этого выжать максимальную скорость?
От: Alex Alexandrov США  
Дата: 17.08.05 19:48
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.

J>
J>for (int *p = data+size*size; p!=data; *(--p) = 99999);
   
J>


Мысль вслух: лучше не гладить память против шерсти. На некоторых процессорах hardware prefetching работает хуже в обратном направлении. Например, Pentium M может отслеживать 12 потоков доступа к памяти в прямом направлении, и только 4 — в обратном.

The Pentium M processor also provides a hardware prefetcher for data.
It can track 12 separate streams in the forward direction and 4 streams in
the backward direction.

... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re: Как из этого выжать максимальную скорость?
От: jazzer Россия Skype: enerjazzer
Дата: 17.08.05 09:00
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>


скомпилировать с оптимизацией по скорости.
и умножение size*size вынести за пределы цикла, хотя упомянутая оптимизация сама это вполне сможет сделать.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Как из этого выжать максимальную скорость?
От: Amethyst  
Дата: 17.08.05 09:00
Оценка:
Здравствуйте, Аноним, Вы писали:


А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }

memset() ?
Почему добро всегда побеждает зло? Потому что историю пишут победители.
Re: Как из этого выжать максимальную скорость?
От: arcman Россия  
Дата: 17.08.05 09:09
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>


для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями
оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"
Re[2]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 09:22
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Аноним, Вы писали:



А>>
А>>    for(unsigned int l=0; l<size*size; l++)
А>>    {
А>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>        data[l] = 99999;        <--- ?
А>>    }
А>>


J>скомпилировать с оптимизацией по скорости.

J>и умножение size*size вынести за пределы цикла, хотя упомянутая оптимизация сама это вполне сможет сделать.

Все равно проигрывает memcpy в 3 раза. vc7.1 release.
Re[2]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 09:27
Оценка:
Здравствуйте, arcman, Вы писали:

A>Здравствуйте, Аноним, Вы писали:



А>>
А>>    for(unsigned int l=0; l<size*size; l++)
А>>    {
А>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>        data[l] = 99999;        <--- ?
А>>    }
А>>


A>для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями

A>оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"

Книги нет А как с указателями?
Re[3]: Как из этого выжать максимальную скорость?
От: jazzer Россия Skype: enerjazzer
Дата: 17.08.05 09:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, arcman, Вы писали:


A>>Здравствуйте, Аноним, Вы писали:



А>>>
А>>>    for(unsigned int l=0; l<size*size; l++)
А>>>    {
А>>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>>        data[l] = 99999;        <--- ?
А>>>    }
А>>>


A>>для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями

A>>оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"

А>Книги нет :( А как с указателями?


вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.
for (int *p = data+size*size; p!=data; *(--p) = 99999);
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 09:42
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, arcman, Вы писали:


A>>>Здравствуйте, Аноним, Вы писали:



А>>>>
А>>>>    for(unsigned int l=0; l<size*size; l++)
А>>>>    {
А>>>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>>>        data[l] = 99999;        <--- ?
А>>>>    }
А>>>>


A>>>для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями

A>>>оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"

А>>Книги нет А как с указателями?


J>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.

J>
J>for (int *p = data+size*size; p!=data; *(--p) = 99999);
   
J>


Сделал. memcpy быстрее в 1.5 раза.
Re: Как из этого выжать максимальную скорость?
От: glyph  
Дата: 17.08.05 09:45
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>

Для чего требуется повышение быстродействия?
На глаз — вынести заполнение массива data из цикла. Попробовать memset, правда, не знаю, будет ли быстрее. Ну а общий подход — смотреть, какие ассемблерные команды генерируются и, если что, переписывать как ассемблерную вставку.
Но зачем, однако?
... << RSDN@Home 1.1.4 beta 3 rev. 193>>
Re[2]: Как из этого выжать максимальную скорость?
От: ssm Россия  
Дата: 17.08.05 09:47
Оценка:
Здравствуйте, arcman, Вы писали:


A>для начала лучше разнести на два цикла,


помоему это должно только замедлить

A>плюс адрессацию с индекса внутри массива заменить на работу с указателями



я всегда считал, что нет разницы между
marks[l] = klas.yel[l];

и
marks + l = klas + l;
Re[2]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 09:50
Оценка:
Здравствуйте, glyph, Вы писали:

G>Здравствуйте, <Аноним>, Вы писали:


А>>
А>>    for(unsigned int l=0; l<size*size; l++)
А>>    {
А>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>        data[l] = 99999;        <--- ?
А>>    }
А>>

G> Для чего требуется повышение быстродействия?
G> На глаз — вынести заполнение массива data из цикла. Попробовать memset, правда, не знаю, будет ли быстрее. Ну а общий подход — смотреть, какие ассемблерные команды генерируются и, если что, переписывать как ассемблерную вставку.
G> Но зачем, однако?

Как memset? memset(data,99999,sizeof(unsigned int)*size*size); не пашет.
Re[3]: Как из этого выжать максимальную скорость?
От: Gleb Alexeev  
Дата: 17.08.05 09:54
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>

ssm>я всегда считал, что нет разницы между
ssm>
ssm>marks[l] = klas.yel[l];
ssm>

ssm>и
ssm>
ssm>marks + l = klas + l;
ssm>

Нет разницы.
Но в цикле есть (правда, не знаю, может оптимизаторы уже умеют сами обращение по индексу в цикле в адресную арифметику преобразовывать).

Псевдокод с индексированием:

for(int i=0; i<n; ++i) {
  char* addr = (char*)array + sizeof(T)*i;
}



Псевдокод с адресной арифметикой:

char *end = (char *)array+sizeof(array)*sizeof(T);
for(char *addr=(char *)array; addr!=end; addr+=sizeof(T)) {
  // используем addr
}


Т.е избавились от умножения в цикле.
Re[5]: Как из этого выжать максимальную скорость?
От: jazzer Россия Skype: enerjazzer
Дата: 17.08.05 10:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сделал. memcpy быстрее в 1.5 раза.


Оптимизацию по скорости включил? Компилятор у тебя какой?

Все эти извращения с указателями нормальный компилятор должен разворачивать в sse-шные инструкции для Intel и в аналогичные, если есть, на других. Более того, он должен оптимизировать и обычный цикл с индексами.

см, например, здесь:
http://rsdn.ru/Forum/Message.aspx?mid=1329039&amp;only=1
Автор: Mr. None
Дата: 16.08.05
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Как из этого выжать максимальную скорость?
От: Gleb Alexeev  
Дата: 17.08.05 10:14
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>

Тут недавно Bell ссылку давал.
Прелюбопытнейшая статья, особенно Duff's device мне понравился.

Кстати, обратите внимание, что если вам надо поддерживать несколько компиляторов, то результаты сравнения memcpy и for-цикла могут сильно варьироваться.
Re[3]: Как из этого выжать максимальную скорость?
От: KHeLeKRoN Россия  
Дата: 17.08.05 10:16
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, arcman, Вы писали:



A>>для начала лучше разнести на два цикла,

ssm>
ssm>помоему это должно только замедлить

AFAIK если код в цикле влезает в L1-кэш, то это оочень убыстрит всю работу (более чем в два раза). И такое разнесение поможет влезть.
And solder won't keep me together (c)
Re: Как из этого выжать максимальную скорость?
От: Bell Россия  
Дата: 17.08.05 10:19
Оценка:
Здравствуйте, Аноним, Вы писали:


Вот в этом топике
Автор:
Дата: 15.08.05
я давал ссылку на статью товарища Александреску. Посмотри, быть может русский крестьянин тебе поможет
Любите книгу — источник знаний (с) М.Горький
Re[2]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 10:23
Оценка:
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Здравствуйте, Аноним, Вы писали:



А>>
А>>    for(unsigned int l=0; l<size*size; l++)
А>>    {
А>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>        data[l] = 99999;        <--- ?
А>>    }
А>>

GA>Тут недавно Bell ссылку давал.
GA>Прелюбопытнейшая статья, особенно Duff's device мне понравился.

GA>Кстати, обратите внимание, что если вам надо поддерживать несколько компиляторов, то результаты сравнения memcpy и for-цикла могут сильно варьироваться.


В статье memcpy всех порулил. Буду его использовать. (Пишу только на vc7.1)
Re[6]: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 17.08.05 10:31
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Аноним, Вы писали:


А>>Сделал. memcpy быстрее в 1.5 раза.


J>Оптимизацию по скорости включил? Компилятор у тебя какой?


J>Все эти извращения с указателями нормальный компилятор должен разворачивать в sse-шные инструкции для Intel и в аналогичные, если есть, на других. Более того, он должен оптимизировать и обычный цикл с индексами.


J>см, например, здесь:

J>http://rsdn.ru/Forum/Message.aspx?mid=1329039&amp;only=1
Автор: Mr. None
Дата: 16.08.05


/o2 vc7.1 Остановился на самом быстром — memcpy.
Re[3]: Как из этого выжать максимальную скорость?
От: Gleb Alexeev  
Дата: 17.08.05 10:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В статье memcpy всех порулил. Буду его использовать. (Пишу только на vc7.1)

Ну а вот с этим:
data[l] = 99999; <--- ?
можно поэкпериментировать.

И вообще, когда будете работать с non-POD'ами, в статье найдете источник вдохновения.
Re: Как из этого выжать максимальную скорость?
От: Слоноежик  
Дата: 17.08.05 11:12
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>


Для начала как говорили разбить на 2 цикла чтоб не иметь проблем с кэшами
и первый код переносить с помощью memcpy или mmx
unsigned int nLength;
unsigned int *pData = data;
nLength = size*size;
nLast = nLength&3;

memcpy(mark, klas.yel, size*size*(sizeof(type)) // 
//данный цикл можно прооптимизить в зависимости от желания юзать всякие расширения асмовские типа ммх(процентов 20 добавит)
for (unsigned int l = 0; i < nLength / 4; ++l)//оптимизатор все равно на сдвиг заменит 
{
  *pData++ = 99999; // поможем оптимизатору явно развернув цикл
  *pData++ = 99999;
  *pData++ = 99999;
  *pData++ = 99999;
}

for(unsigned int l = 0; i < nLast; ++l)
{
  *pData++ = 99999;
}
для забивания гвоздя надо выбирать правильный микроскоп.
Re[2]: Как из этого выжать максимальную скорость?
От: Gleb Alexeev  
Дата: 17.08.05 11:16
Оценка:
Здравствуйте, Слоноежик, Вы писали:


С>for (unsigned int l = 0; i < nLength / 4; ++l)//оптимизатор все равно на сдвиг заменит

С>{
С> *pData++ = 99999; // поможем оптимизатору явно развернув цикл
С> *pData++ = 99999;
С> *pData++ = 99999;
С> *pData++ = 99999;
С>}
Если nLength не кратна 4, будут проблемы.
Re[3]: Как из этого выжать максимальную скорость?
От: Слоноежик  
Дата: 17.08.05 11:30
Оценка:
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Здравствуйте, Слоноежик, Вы писали:



GA>Если nLength не кратна 4, будут проблемы.


для этого был добавлен код(в посте он есть)

nLast = nLength&3;
for(unsigned int l = 0; i < nLast; ++l)
{
  *pData++ = 99999;
}
для забивания гвоздя надо выбирать правильный микроскоп.
Re[4]: Как из этого выжать максимальную скорость?
От: Gleb Alexeev  
Дата: 17.08.05 11:36
Оценка:
Здравствуйте, Слоноежик, Вы писали:


GA>>Если nLength не кратна 4, будут проблемы.


С>для этого был добавлен код(в посте он есть)


С>
С>nLast = nLength&3;
С>for(unsigned int l = 0; i < nLast; ++l)
С>{
С>  *pData++ = 99999;
С>}
С>

Не заметил, ппйду выпью йаду .
Re: Как из этого выжать максимальную скорость?
От: Vutik  
Дата: 17.08.05 12:59
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>

memcpy само собой
ну и
void fill_n(OutIt first, Size n, const T& x);
Re[4]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 17.08.05 13:11
Оценка:
A>>>для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями
A>>>оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"

А>>Книги нет А как с указателями?


J>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.


Думаю, нет, уверен, что с более-менее нормальным компилятором это даст ровно такой же код, как и приведенный начальный цикл. Все более-менее адекватные компиляторы уже давно индексную и адресную арифметику сводят к одному коду.
Вот что дается VC6:

; 204  :         int data1[10000];
; 205  :         
; 206  :         for (int *b = data1, *e = data1 + 10000;  b < e; ++b)
; 207  :             *b = 99999;

    mov    ecx, 10000                ; 00002710H
    mov    eax, 99999                ; 0001869fH
    lea    edi, DWORD PTR _data1$98162[esp+40008]
    rep stosd



; 204  :         int data1[10000];
; 205  :         
; 206  : //        for (int *b = data1, *e = data1 + 10000;  b < e; ++b)
; 207  : //            *b = 99999;
; 208  :         for(unsigned int l=0; l < 10000; ++l)
; 209  :             data1[l] = 99999;

    mov    ecx, 10000                ; 00002710H
    mov    eax, 99999                ; 0001869fH
    lea    edi, DWORD PTR _data1$98162[esp+40008]
    rep stosd


Найдите 10 отличий
Единственное, что тут можно сделать — разнести на 2 цикла.. и то сомневаюсь, что это поможет:

; 204  :         int data1[10000],data2[10000], data3[10000];
; 205  :         
; 206  : //        for (int *b = data1, *e = data1 + 10000;  b < e; ++b)
; 207  : //            *b = 99999;
; 208  :         for(unsigned int l=0; l < 10000; ++l)
; 209  :         {    
; 210  :             data1[l] = 99999;
; 211  :             data2[l] = data3[l];

    mov    ecx, 10000                ; 00002710H
    lea    esi, DWORD PTR _data3$98164[esp+80012]
    lea    edi, DWORD PTR _data2$98163[esp+80012]
    mov    eax, 99999                ; 0001869fH
    rep movsd
    mov    ecx, 10000                ; 00002710H
    lea    edi, DWORD PTR _data1$98162[esp+80012]
    rep stosd

В общем, компилятор и сам не дурак. Другое дело, что для различных процессоров stosd и movsd не всегда оптимальны — например, для 486 было оптимально делать цикл + мув, на остальных, безусловно, быстрее будет через fpu\sse\mmx, ну тут оптимизатор настроить на соотв. процессор и получим нужные эффект.

Начальный пример автора сложнее — там структура в качестве источника данных используется, поэтому насчет применения там memcpy что то я не уверен. А вот что для структуры:

; 203  :     {
; 204  :         int data1[10000],data2[10000];
; 205  :         int k = GetTickCount();

    call    DWORD PTR __imp__GetTickCount@0
    mov    ebx, eax

; 206  :         struct {int p1; int p2;} data3[10000];
; 207  :         
; 208  : //        for (int *b = data1, *e = data1 + k;  b < e; ++b)
; 209  : //            *b = 99999;
; 210  :         for(unsigned int l=0; l < k; ++l)

    xor    edx, edx
    test    ebx, ebx
    jbe    SHORT $L98179
    mov    ecx, ebx
    mov    eax, 99999                ; 0001869fH
    lea    edi, DWORD PTR _data1$98162[esp+120016]
    lea    esi, DWORD PTR _data3$98175[esp+120020]
    rep stosd
$L98177:

; 211  :         {    
; 212  :             data1[l] = 99999;
; 213  :             data2[l] = data3[l].p2;

    mov    ecx, DWORD PTR [esi]
    add    esi, 8
    mov    DWORD PTR _data2$98163[esp+edx*4+120016], ecx
    inc    edx
    cmp    edx, ebx
    jb    SHORT $L98177
$L98179:

; 214  :         }

Комментарии излишни... Пожалуй, что все-таки стоило второй цикл несколько лучше прооптимизировать, например, там можно избавиться от второго счетчика. Но это особых различий в производительности не даст.

Так что максимум, что может сделать автор — посчитать сначала границы цикла, а не делать это в каждой итерации... да и то это соптимизуется компилятором, исключая особые случаи, он посчитает границы цикла изначально.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Как из этого выжать максимальную скорость?
От: Erop Россия  
Дата: 17.08.05 16:24
Оценка:
Здравствуйте, jazzer, Вы писали:

J>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.

J>
J>for (int *p = data+size*size; p!=data; *(--p) = 99999);
   
J>


А так точно быстрее? Казалось бы, нормальный компилятор и сам могёт такое навернуть. Случай-то типичный . А вот распутать эти все оптимизации обратно -- не факт.

Вы вот лучше признайтесь, каковы размеры всех этих данных?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Как из этого выжать максимальную скорость?
От: Alex Alexandrov США  
Дата: 17.08.05 19:48
Оценка:
Здравствуйте, KHeLeKRoN, Вы писали:

KHL>AFAIK если код в цикле влезает в L1-кэш, то это оочень убыстрит всю работу (более чем в два раза). И такое разнесение поможет влезть.


Дополнительно: в коротком цикле больше вероятность уместить все необходимые данные в регистры. Еще у некоторых компиляторов есть прагмы для подсказки компилятору, что области данных гарантированно не пересекаются — тоже может дать серьезный выигрыш.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re[5]: Как из этого выжать максимальную скорость?
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.05 08:24
Оценка:
Здравствуйте, Erop, Вы писали:

E>А так точно быстрее?


а я и не говорил, что быстрее, я отвечал на вопрос: "А как с указателями?"
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Как из этого выжать максимальную скорость?
От: Аноним  
Дата: 18.08.05 11:50
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>



Если кому интересно, то остановился на memcpy и memset (что не 99999 не принципиально, главное большое число).
Re[5]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 18.08.05 18:09
Оценка:
Здравствуйте, Andrew S, Вы писали:

A>>>>для начала лучше разнести на два цикла, плюс адрессацию с индекса внутри массива заменить на работу с указателями

A>>>>оптимизация записи в память подробно расписанна в книге Криса Касперски — "Техника оптимизации программ"

А>>>Книги нет А как с указателями?


J>>вместо инкремента индекса l++ и обращения по нему data[l] инкрементишь указатели на элементы массива, начиная с data, а лучше — заканчивая, т.е.


AS>Думаю, нет, уверен, что с более-менее нормальным компилятором это даст ровно такой же код, как и приведенный начальный цикл. Все более-менее адекватные компиляторы уже давно индексную и адресную арифметику сводят к одному коду.

AS>Вот что дается VC6:

AS>
AS>; 204  :         int data1[10000];
AS>; 205  :         
AS>; 206  :         for (int *b = data1, *e = data1 + 10000;  b < e; ++b)
AS>; 207  :             *b = 99999;

AS>    mov    ecx, 10000                ; 00002710H
AS>    mov    eax, 99999                ; 0001869fH
AS>    lea    edi, DWORD PTR _data1$98162[esp+40008]
AS>    rep stosd

AS>



быстрее всё-таки так

int *p = data1+9;
do
{
*p=9999;
}while(p-- != data1);
Re[6]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 18.08.05 19:07
Оценка:
F>быстрее всё-таки так

F> int *p = data1+9;

F> do
F> {
F> *p=9999;
F> }while(p-- != data1);

Быстрее так быть не может по нескольким причинам:
1. Результирующий код одинаков, в случае по крайней мере моего компилятора.
2. Если компилятор и сформирует "вывернутый" код, на многих процессорах обратная запись гораздо медленнее прямой.

А вообще, лучше приведите тот код, что у вас получился в результате — тогда и будет о чем говорить. А просто кидаться необоснованными ничем заявлениями все могут...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[7]: Как из этого выжать максимальную скорость?
От: arcman Россия  
Дата: 19.08.05 08:35
Оценка:
Повторяюсь, но всё же:
Есть хорошая, полностью практическая, книжка дающая однозначные ответы и рекомендации на subj
"Крис Касперски — Техника оптимизации программ. Эффективное использование памяти" http://findbook.ru/search/d0?s=1&amp;pvalue=%D2%E5%F5%ED%E8%EA%E0+%EE%EF%F2%E8%EC%E8%E7%E0%F6%E8%E8+%EF%F0%EE%E3%F0%E0%EC%EC&amp;r=0&amp;ptype=1)
Все аспекты связанные с копированием памяти там подробно разобраны.
Книга существует также в электронном виде, но администрация форума не разрешает её публиковать. Если автор разрешит публикацию в интернете, то я выложу линки
Re[7]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 19.08.05 09:11
Оценка:
Здравствуйте, Andrew S, Вы писали:

F>>быстрее всё-таки так


F>> int *p = data1+9;

F>> do
F>> {
F>> *p=9999;
F>> }while(p-- != data1);

AS>Быстрее так быть не может по нескольким причинам:

AS>1. Результирующий код одинаков, в случае по крайней мере моего компилятора.

критерием для меня был конечно результирующий код

AS>2. Если компилятор и сформирует "вывернутый" код, на многих процессорах обратная запись гораздо медленнее прямой.


это я плохо понимаю о чём( про "вывернутость" ), может с точки зрения человека это и так, но только с непривычки
я как раз смотрел на разных RISC архитектурах

AS>А вообще, лучше приведите тот код, что у вас получился в результате — тогда и будет о чем говорить. А просто кидаться необоснованными ничем заявлениями все могут...


ну вот например для ARM который был под рукой
void test1()
{
    int data1[10];

    int *p = data1+9;
    do
    {
        *p=9999;
    }while(p-- != data1);
}
void test2()
{
    int data1[10];

    int *b, *e;
    for (b = data1, e = data1 + 10;  b < e; ++b)
        *b = 9999;
}
int main()
{
    test1();
    test2();


    return 0;
}
test1    [0xe24dd028]   sub      r13,r13,#0x28
000080ac    [0xe28d0024]   add      r0,r13,#0x24
000080b0    [0xe1a00000]   nop      
000080b4    [0xe59f1064]   ldr      r1,0x00008120 ; = #0x0000270f
000080b8    [0xe5801000]   str      r1,[r0,#0]
000080bc    [0xe2401004]   sub      r1,r0,#4
000080c0    [0xe1a00001]   mov      r0,r1
000080c4    [0xe24d2004]   sub      r2,r13,#4
000080c8    [0xe1510002]   cmp      r1,r2
000080cc    [0x1afffff8]   bne      0x80b4  ; (test1 + 0xc)
000080d0    [0xe28dd028]   add      r13,r13,#0x28
000080d4    [0xe1a0f00e]   mov      pc,r14
test2    [0xe24dd028]   sub      r13,r13,#0x28
000080dc    [0xe1a0000d]   mov      r0,r13
000080e0    [0xe28d1028]   add      r1,r13,#0x28
000080e4    [0xe1500001]   cmp      r0,r1
000080e8    [0x2a000005]   bcs      0x8104  ; (test2 + 0x2c)
000080ec    [0xea000001]   b        0x80f8  ; (test2 + 0x20)
000080f0    [0xe2800004]   add      r0,r0,#4
000080f4    [0xeafffffa]   b        0x80e4  ; (test2 + 0xc)
000080f8    [0xe59f2020]   ldr      r2,0x00008120 ; = #0x0000270f
000080fc    [0xe5802000]   str      r2,[r0,#0]
00008100    [0xeafffffa]   b        0x80f0  ; (test2 + 0x18)
00008104    [0xe28dd028]   add      r13,r13,#0x28
00008108    [0xe1a0f00e]   mov      pc,r14


я сначала смотрел для 8-битника, там разница даже в 2 слова
Re[8]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 19.08.05 09:33
Оценка:
ЗAS>>2. Если компилятор и сформирует "вывернутый" код, на многих процессорах обратная запись гораздо медленнее прямой.

F>это я плохо понимаю о чём( про "вывернутость" ), может с точки зрения человека это и так, но только с непривычки

F>я как раз смотрел на разных RISC архитектурах

http://www.rsdn.ru/Forum/Message.aspx?mid=1332782&amp;only=1
Автор: Alex Alexandrov
Дата: 17.08.05



AS>>А вообще, лучше приведите тот код, что у вас получился в результате — тогда и будет о чем говорить. А просто кидаться необоснованными ничем заявлениями все могут...


При чем здесь arm? В данном топике речь идет о линейке компиляторов VC под ia32, конкретно — vc7.1. Давайте не будем рассматривать _сильно_ другие (какие, кстати?) компиляторы, поскольку это явно уход от темы. Я не уверен, что компилятор, приведенный вам, достаточно удачно оптимизирует.
Точнее уверен, что неудачно, поскольку вот что формирует в приведенном вами коде VC6:

; 204  :         int data1[10000];
; 205  :         int *p = data1 + 10000 - 1;

    lea    eax, DWORD PTR _data1$98162[esp+80000]
$L98164:

; 206  :         do
; 207  :         {
; 208  :             *p=9999;

    mov    DWORD PTR [eax], 9999            ; 0000270fH

; 209  :         }
; 210  :         while(p-- != data1);

    lea    ecx, DWORD PTR _data1$98162[esp+40004]
    mov    edx, eax
    sub    eax, 4
    cmp    edx, ecx
    jne    SHORT $L98164


После этого вы будете утверждать, что это вариант быстрее? Не ститая того, что как уже говорилось, обратное чтение сложнее кешировать и выбирать.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[9]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 23.08.05 07:06
Оценка:
Здравствуйте, Andrew S, Вы писали:

ЗAS>>>2. Если компилятор и сформирует "вывернутый" код, на многих процессорах обратная запись гораздо медленнее прямой.


F>>это я плохо понимаю о чём( про "вывернутость" ), может с точки зрения человека это и так, но только с непривычки

F>>я как раз смотрел на разных RISC архитектурах

AS>http://www.rsdn.ru/Forum/Message.aspx?mid=1332782&amp;only=1
Автор: Alex Alexandrov
Дата: 17.08.05


весь windows не переделать, а в приложении или даже коде драйвера можно писать правильно, это всё равно не будет даже 1/3


AS>>>А вообще, лучше приведите тот код, что у вас получился в результате — тогда и будет о чем говорить. А просто кидаться необоснованными ничем заявлениями все могут...


AS>При чем здесь arm? В данном топике речь идет о линейке компиляторов VC под ia32, конкретно — vc7.1. Давайте не будем рассматривать _сильно_ другие (какие, кстати?) компиляторы, поскольку это явно уход от темы. Я не уверен, что компилятор, приведенный вам, достаточно удачно оптимизирует.

AS>Точнее уверен, что неудачно, поскольку вот что формирует в приведенном вами коде VC6:

AS>
AS>; 204  :         int data1[10000];
AS>; 205  :         int *p = data1 + 10000 - 1;

AS>    lea    eax, DWORD PTR _data1$98162[esp+80000]
AS>$L98164:

AS>; 206  :         do
AS>; 207  :         {
AS>; 208  :             *p=9999;

AS>    mov    DWORD PTR [eax], 9999            ; 0000270fH

AS>; 209  :         }
AS>; 210  :         while(p-- != data1);

AS>    lea    ecx, DWORD PTR _data1$98162[esp+40004]
AS>    mov    edx, eax
AS>    sub    eax, 4
AS>    cmp    edx, ecx
AS>    jne    SHORT $L98164
AS>


попробуйте так
    int data1[10000];

    int l = 10000;
    do
    {
        data1[--l]=99999;
    }while(l);

и смотреть без оптимизации бесполезно
кстати для тестов я использовал компиляторы
http://htsoft.com/products/picccompiler.php
для которого довольно хорошо известо какой должен быть минимальный ассемблерный код
и компилятором отсюда
http://www.arm.com/support/downloads/info/4554.html


AS>После этого вы будете утверждать, что это вариант быстрее? Не ститая того, что как уже говорилось, обратное чтение сложнее кешировать и выбирать.


ну про обратное чтение я уже сказал, что есть ещё код windows
и посмотрите на vc7.1 или VC6, но с оптимизацией
Re[10]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.08.05 07:55
Оценка:
F>попробуйте так
F>
F>    int data1[10000];

F>    int l = 10000;
F>    do
F>    {
F>        data1[--l]=99999;
F>    }while(l);
F>

F>и смотреть без оптимизации бесполезно

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

Вот ваш последний вариант:

; 204  :     int data1[10000];
; 205  : 
; 206  :         int l = 10000;

    lea    eax, DWORD PTR _data1$98162[esp+80004]
    mov    ecx, 10000                ; 00002710H
$L98164:

; 207  :         do
; 208  :         {
; 209  :             data1[--l]=99999;

    sub    eax, 4

; 210  :         }while(l);

    dec    ecx
    mov    DWORD PTR [eax], 99999            ; 0001869fH
    jne    SHORT $L98164


F>кстати для тестов я использовал компиляторы

F>http://htsoft.com/products/picccompiler.php
F>для которого довольно хорошо известо какой должен быть минимальный ассемблерный код
F>и компилятором отсюда
F>http://www.arm.com/support/downloads/info/4554.html

Значит, компиляторы не очень, если они такой элементарный прямой цикл делают больше обратного.

F>ну про обратное чтение я уже сказал, что есть ещё код windows


При чем тут это? У вас что, тайм слайс истекает каждую итерация цикла, что код виндовс будет кардинальным образом влиять на быстродействие? К тоже вам уже несколько раз напомнили, что процессоры оптимизированы на прямое чтение\запись памяти, а не обратно. Прямой цикл VC6 явно лучше оптимизирует (и явно оптимизация заточена именно на прямой цикл), прямой цикл работает быстрее на многих архитектурах, ну и наконец — прямой цикл используется чаще всего. В обшем, на мой взгляд, ваше доводы не состоятельны.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Как из этого выжать максимальную скорость?
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 23.08.05 13:36
Оценка:
Здравствуйте, Аноним, Вы писали:


А>
А>    for(unsigned int l=0; l<size*size; l++)
А>    {
А>        marks[l] = klas.yel[l]; <--- memcpy?
А>        data[l] = 99999;        <--- ?
А>    }
А>


Для строки
data[l] = 99999;
можно попробовать заполнить несколько первых значений, а потом размножить с помощью memcpy.
Re[2]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.08.05 13:56
Оценка:
A>Для строки
data[l] = 99999;
можно попробовать заполнить несколько первых значений, а потом размножить с помощью memcpy.


И каким образом movsd будет быстрее stosd?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Как из этого выжать максимальную скорость?
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 23.08.05 14:34
Оценка:
Здравствуйте, Andrew S, Вы писали:

A>>Для строки
data[l] = 99999;
можно попробовать заполнить несколько первых значений, а потом размножить с помощью memcpy.


AS>И каким образом movsd будет быстрее stosd?


Я всего-лишь предположил В исходном сообщении не было намеков ни на платформу, ни даже на typeof(data[l]).
Re[4]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.08.05 14:39
Оценка:
A>>>Для строки
data[l] = 99999;
можно попробовать заполнить несколько первых значений, а потом размножить с помощью memcpy.


AS>>И каким образом movsd будет быстрее stosd?


A>Я всего-лишь предположил В исходном сообщении не было намеков ни на платформу, ни даже на typeof(data[l]).


Да ну?

http://www.rsdn.ru/Forum/Message.aspx?mid=1331229&amp;only=1
Автор:
Дата: 17.08.05


В любом случае — перенос почти всегда медленее заливки числом. Если только заранее несколько значений не посчитать в регистры. Но никак не в память.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[11]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 23.08.05 18:09
Оценка:
я наверное чего-то не догоняю, объясните, пожалуйста, если не сложно

; 21   :     int data11[10000];
; 22   : 
; 23   :     int *b1, *e1;
; 24   :     for (b1 = data11, e1 = data11 + 10000;  b1 < e1; ++b1)

    lea    eax, DWORD PTR _data11$[ebp]
    mov    DWORD PTR _b1$[ebp], eax
    lea    ecx, DWORD PTR _data11$[ebp+40000]
    mov    DWORD PTR _e1$[ebp], ecx
    jmp    SHORT $L234
$L235:
    mov    edx, DWORD PTR _b1$[ebp]
    add    edx, 4
    mov    DWORD PTR _b1$[ebp], edx
$L234:
    mov    eax, DWORD PTR _b1$[ebp]
    cmp    eax, DWORD PTR _e1$[ebp]
    jae    SHORT $L236

; 25   :         *b1 = 99999;

    mov    ecx, DWORD PTR _b1$[ebp]
    mov    DWORD PTR [ecx], 99999            ; 0001869fH
    jmp    SHORT $L235
$L236:

; 26   : 
; 27   : }


14 команд против 11

; 30   :     int data11[10000];
; 31   :     int *p1 = data11+9999;

    lea    eax, DWORD PTR _data11$[ebp+39996]
    mov    DWORD PTR _p1$[ebp], eax
$L241:

; 34   :         *p1=99999;

    mov    ecx, DWORD PTR _p1$[ebp]
    mov    DWORD PTR [ecx], 99999            ; 0001869fH

; 35   :     }while(p1-- != data11);

    mov    edx, DWORD PTR _p1$[ebp]
    lea    eax, DWORD PTR _data11$[ebp]
    mov    ecx, DWORD PTR _p1$[ebp]
    sub    ecx, 4
    mov    DWORD PTR _p1$[ebp], ecx
    cmp    edx, eax
    jne    SHORT $L241

; 36   : }


а как правильный листинг сгенерить с
rep stosd
?
Re[12]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.08.05 20:58
Оценка:
F>я наверное чего-то не догоняю, объясните, пожалуйста, если не сложно

F>а как правильный листинг сгенерить с

F>rep stosd
F>?

Использовать более-менее нормальный компилятор (в мое случае — VC6), оптимизацию на скорость, опция генерить листинг в asm файлы, релиз.
Остальное все по умолчанию (впрочем, оптимизация на скорость в VC6 тоже по умолчанию).
Вроде все
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[13]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 26.08.05 12:54
Оценка:
Здравствуйте, Andrew S, Вы писали:

F>>я наверное чего-то не догоняю, объясните, пожалуйста, если не сложно


F>>а как правильный листинг сгенерить с

F>>rep stosd
F>>?

AS>Использовать более-менее нормальный компилятор (в мое случае — VC6), оптимизацию на скорость, опция генерить листинг в asm файлы, релиз.

AS>Остальное все по умолчанию (впрочем, оптимизация на скорость в VC6 тоже по умолчанию).
AS>Вроде все

Использую стандартную Visual C++ 6.0
оптимизация на скорость /O2
листинг в asm файлы, релиз.

; 21   :     int data11[10000];
; 22   : 
; 23   :     int *b1, *e1;
; 24   :     for (b1 = data11, e1 = data11 + 10000;  b1 < e1; ++b1)

    lea    eax, DWORD PTR _data11$[ebp]
    mov    DWORD PTR _b1$[ebp], eax
    lea    ecx, DWORD PTR _data11$[ebp+40000]
    mov    DWORD PTR _e1$[ebp], ecx
    jmp    SHORT $L234
$L235:
    mov    edx, DWORD PTR _b1$[ebp]
    add    edx, 4
    mov    DWORD PTR _b1$[ebp], edx
$L234:
    mov    eax, DWORD PTR _b1$[ebp]
    cmp    eax, DWORD PTR _e1$[ebp]
    jae    SHORT $L236

; 25   :         *b1 = 99999;

    mov    ecx, DWORD PTR _b1$[ebp]
    mov    DWORD PTR [ecx], 99999            ; 0001869fH
    jmp    SHORT $L235
$L236:

; 26   : 
; 27   : }


14 : 11

и только
Re[14]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 26.08.05 13:24
Оценка:
AS>>Использовать более-менее нормальный компилятор (в мое случае — VC6), оптимизацию на скорость, опция генерить листинг в asm файлы, релиз.
AS>>Остальное все по умолчанию (впрочем, оптимизация на скорость в VC6 тоже по умолчанию).
AS>>Вроде все

F>Использую стандартную Visual C++ 6.0

F>оптимизация на скорость /O2

Сервис паки ставили? У меня 6-й. До этого еще процессор пак 5-й стоял, но вроде как 6-й сервис пак его убил.
Обманывать мне вас смысла нет — да и смысл, если VC6 генерит именно это, не сам же я такой код нарисовал
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Как из этого выжать максимальную скорость?
От: Erop Россия  
Дата: 30.08.05 06:32
Оценка:
Здравствуйте, Andrew S, Вы писали:


AS>В любом случае — перенос почти всегда медленее заливки числом. Если только заранее несколько значений не посчитать в регистры. Но никак не в память.


А кэш?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Как из этого выжать максимальную скорость?
От: gear nuke  
Дата: 30.08.05 07:16
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Andrew S, Вы писали:


AS>>В любом случае — перенос почти всегда медленее заливки числом. Если только заранее несколько значений не посчитать в регистры. Но никак не в память.


E>А кэш?


А он берёт данные из памяти, которая на порядок (!) медленнее. И на больших объёмах данных, память самое узкое место.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[7]: Как из этого выжать максимальную скорость?
От: alnsn Великобритания http://nasonov.blogspot.com
Дата: 30.08.05 09:50
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Erop, Вы писали:


E>>Здравствуйте, Andrew S, Вы писали:


AS>>>В любом случае — перенос почти всегда медленее заливки числом. Если только заранее несколько значений не посчитать в регистры. Но никак не в память.


E>>А кэш?


GN>А он берёт данные из памяти, которая на порядок (!) медленнее. И на больших объёмах данных, память самое узкое место.


Если читать в последний раз записанный участок памяти, то наверное он будет в кэше. Я попробовал сравнить обычный цикл с таким копированием на i86. Результаты почти не отличаются. Пробовал копировать пачками по 4 и 8 интов. На спарке это метод заметно медленнее.
Re[15]: Как из этого выжать максимальную скорость?
От: front242  
Дата: 30.08.05 12:17
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>>>Использовать более-менее нормальный компилятор (в мое случае — VC6), оптимизацию на скорость, опция генерить листинг в asm файлы, релиз.

AS>>>Остальное все по умолчанию (впрочем, оптимизация на скорость в VC6 тоже по умолчанию).
AS>>>Вроде все

F>>Использую стандартную Visual C++ 6.0

F>>оптимизация на скорость /O2

AS>Сервис паки ставили? У меня 6-й. До этого еще процессор пак 5-й стоял, но вроде как 6-й сервис пак его убил.

AS>Обманывать мне вас смысла нет — да и смысл, если VC6 генерит именно это, не сам же я такой код нарисовал

у меня стоит sp6

Вы не могли бы код всей функции привести, пожалуйста, ну типа

void test()
{
    int data1[10000];

    int *b1, *e1;
    for (b1 = data1, e1 = data1 + 10000;  b1 < e1; ++b1)
        *b1 = 99999;

}

; 7    : {

    push    ebp
    mov    ebp, esp
    mov    eax, 40008                ; 00009c48H
    call    __chkstk

; 8    :     int data1[10000];
; 9    : 
; 10   :     int *b1, *e1;
; 11   :     for (b1 = data1, e1 = data1 + 10000;  b1 < e1; ++b1)

    lea    eax, DWORD PTR _data1$[ebp]
    mov    DWORD PTR _b1$[ebp], eax
    lea    ecx, DWORD PTR _data1$[ebp+40000]
    mov    DWORD PTR _e1$[ebp], ecx
    jmp    SHORT $L582
$L583:
    mov    edx, DWORD PTR _b1$[ebp]
    add    edx, 4
    mov    DWORD PTR _b1$[ebp], edx
$L582:
    mov    eax, DWORD PTR _b1$[ebp]
    cmp    eax, DWORD PTR _e1$[ebp]
    jae    SHORT $L584

; 12   :         *b1 = 99999;

    mov    ecx, DWORD PTR _b1$[ebp]
    mov    DWORD PTR [ecx], 99999            ; 0001869fH
    jmp    SHORT $L583
$L584:

; 13   : 
; 14   : }
Re[16]: Как из этого выжать максимальную скорость?
От: Andrew S Россия http://alchemy-lab.com
Дата: 30.08.05 12:45
Оценка:
F>Вы не могли бы код всей функции привести, пожалуйста

Вот:

void test()
{
    int data1[10000];
    for (int *b1 = data1, *e1 = data1 + 10000;  b1 < e1; ++b1)
        *b1 = 99999;
    printf("", data1);
}


?test@@YAXXZ PROC NEAR                    ; test, COMDAT

; 192  : {

    mov    eax, 40000                ; 00009c40H
    call    __chkstk
    push    edi

; 193  :     int data1[10000];
; 194  :     for (int *b1 = data1, *e1 = data1 + 10000;  b1 < e1; ++b1)
; 195  :         *b1 = 99999;

    mov    ecx, 10000                ; 00002710H
    mov    eax, 99999                ; 0001869fH
    lea    edi, DWORD PTR _data1$[esp+40004]
    rep stosd

; 196  :     printf("", data1);

    lea    eax, DWORD PTR _data1$[esp+40004]
    push    eax
    push    OFFSET FLAT:??_C@_00A@?$AA@        ; `string'
    call    DWORD PTR __imp__printf
    add    esp, 8
    pop    edi

; 197  : }

    add    esp, 40000                ; 00009c40H
    ret    0
?test@@YAXXZ ENDP                    ; test
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[8]: Как из этого выжать максимальную скорость?
От: gear nuke  
Дата: 30.08.05 15:02
Оценка:
Здравствуйте, alnsn

AS>>>>В любом случае — перенос почти всегда медленее заливки числом. Если только заранее несколько значений не посчитать в регистры. Но никак не в память.


E>>>А кэш?


GN>>А он берёт данные из памяти, которая на порядок (!) медленнее. И на больших объёмах данных, память самое узкое место.


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

Верно, хотя зависит от метода записи в память. Для x86 cуществуют команды, пишущие в обход кеша (компиляторы С их обычно не гененрируют).

A>Я попробовал сравнить обычный цикл с таким копированием на i86. Результаты почти не отличаются. Пробовал копировать пачками по 4 и 8 интов.

Очень многое зависит от объёма копируемых данных. На больших объёмах можно получить выигрыш до 3х раз(пример, для P4 это не очень актуально, поскольку там rep movsd ускорена аппаратно).
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Как из этого выжать максимальную скорость?
От: Vutik  
Дата: 18.10.05 13:03
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, arcman, Вы писали:


A>>>Здравствуйте, Аноним, Вы писали:



А>>>>
А>>>>    for(unsigned int l=0; l<size*size; l++)
А>>>>    {
А>>>>        marks[l] = klas.yel[l]; <--- memcpy?
А>>>>        data[l] = 99999;        <--- ?
А>>>>    }
А>>>>

можно
std::copy + std::fill
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.