LINUX.ORG.RU

Медленная запись в память?


0

0

Туплю в дрова.
double elements[100000];

void func1(double *arr)
{
int i;
double j=1;
for(i=0;i<100000;i++)
{
arr[i]=j;
}
}

void func2(double *arr)
{
int i;
double j;
for(i=0;i<100000;i++)
{
j=arr[i];
}
}

int main()
{
int i;
for(i=0;i<10000;i++)
{
func1(elements);
}
}

Если вызываю func1 из main
time ./test1 12,63s user 0,25s system 69% cpu 18,626 total
если func2 из main
time ./test1 4,93s user 0,10s system 74% cpu 6,713 total
Почему разница аж в 3 раза?

★★★

У меня совпало.

[testdir]> cat test.c
#include <stdio.h>

double elements[100000];

void func1(double *arr)
{
int i;
double j=1;
for(i=0;i<100000;i++)
{
arr[i]=j;
}
}

void func2(double *arr)
{
int i;
double j;
for(i=0;i<100000;i++)
{
j=arr[i];
}
}

int main(int argc, char** argv)
{
int i;
if (argc == 1) {
 printf("func1\n");
for(i=0;i<10000;i++)
{
func1(elements);
}
}
else {
 printf("func2\n");
for(i=0;i<10000;i++)
{
func2(elements);
}
};
}

[testdir]> gcc test.c
[testdir]> time ./a.out
func1

real    0m2.559s
user    0m2.559s
sys     0m0.000s
[testdir]> time ./a.out 1
func2

real    0m2.534s
user    0m2.532s
sys     0m0.000s

Jini ★★
()
Ответ на: комментарий от Jini

Хм.... Опции компиляции? Версия gcc? C -O0 билдил?

Svoloch ★★★
() автор топика
Ответ на: комментарий от Svoloch

--- test-old.c  2008-02-09 02:40:06.000000000 +0300
+++ test.c      2008-02-09 02:40:08.000000000 +0300
@@ -27,14 +27,14 @@
 int i;
 if (argc == 1) {
  printf("func1\n");
-for(i=0;i<10000;i++)
+for(i=0;i<100000;i++)
 {
 func1(elements);
 }
 }
 else {
  printf("func2\n");
-for(i=0;i<10000;i++)
+for(i=0;i<100000;i++)
 {
 func2(elements);
 }
[testdir]> time ./a.out  
func1

real    0m25.647s
user    0m25.647s
sys     0m0.000s
[testdir]> time ./a.out 1
func2

real    0m25.264s
user    0m25.264s
sys     0m0.001s
[testdir]> gcc test.c -O0
[testdir]> time ./a.out
func1

real    0m27.755s
user    0m27.715s
sys     0m0.001s
[testdir]> time ./a.out 1
func2

real    0m23.197s
user    0m23.161s
sys     0m0.003s

Результаты, похоже, имеют погрешность около 10% (интересно, почему?..)
Не только приведённые, я по нескольку раз тест прогнал.

Ежли чё --- у меня 64битная архитектура, два ядра, в фоне висит только StrongDC
под вайном.

Jini ★★
()
Ответ на: комментарий от Jini

Вот для 500000. Похоже, разница всё-таки есть, но не такая большая.

[testdir]> gcc test.c -O0
[testdir]> time ./a.out  
func1

real    2m26.431s
user    2m26.435s
sys     0m0.000s
[testdir]> time ./a.out 1
func2

real    2m6.388s
user    2m6.392s
sys     0m0.002s

Jini ★★
()
Ответ на: комментарий от Jini

Debian , Celeron 1700.
Стабильная повторяемось - запись в 3 раза медленне для gcc 2.95 3.3 4.1.

Svoloch ★★★
() автор топика

arr[i]=j;

j=arr[i];

Очевидно, что запись в регистр происходит быстрее чем в память. И чтение из памяти быстрее записи в оную.

На различия можно посмотреть при помощи gcc -S

stassats ★★★★
()
Ответ на: комментарий от stassats

> И чтение из памяти быстрее записи в оную

Как раз наоборот, потому что во время предзаряда в память можно писать, но читать нельзя.
Поэтому, каким бы пародоксальным это не казалось, но чтение из памяти МЕДЛЕННЕЕ записи.
Причём разница получается довольно существенная.

Agent666
()

А почему слово кэш не прозвучало??

Ты много раз повторяешь цикл чтения -- большая часть в кэше.

Когда же ты много раз повторяешь цикл записи, то запись идет в память (видимо, логика процессора не проверяет пытаешься ли ты записать то же самое что там уже есть)

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

Что в кэше? Массив? Не понимаю зачем его кэшировать если при -O0 не проводится оптимизаий. Если на уровне системы - то страница памяти что при чтении что при записи одинаково должна выдернуться из свопа, если конечно засвопится...

Svoloch ★★★
() автор топика
Ответ на: комментарий от Svoloch

> Что в кэше? Массив? Не понимаю зачем его кэшировать если при -O0 не проводится оптимизаий. Если на уровне системы - то страница памяти что при чтении что при записи одинаково должна выдернуться из свопа, если конечно засвопится...

что курил?? Кэширование на уровне процессора а не системы. И кэщируется не по страницам а по кэш-линиям

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> ты читаешь из кэша а пишешь в память

Не совсем - пишет тоже в кэш, только есть два механизма: с отложенной записью и со сквозной записью.

Второй механизм означает, что при записи в кэш происходит запись и в память, первый, -

что запись в память производится при необходимости измененения тэгов записей кэша.

На 100%, конечно, не уверен, но думаю, что линух использует первый из вышеназванных режимов,

обратное просто нелогично.

Agent666
()
Ответ на: комментарий от Agent666

это без разницы -- все равно в случае с записью твой throughput лимитирован by throughput канала в память. А в случае чтения лимитирован by throughput канала в кэш.

dilmah ★★★★★
()
Ответ на: комментарий от Agent666

> думаю, что линух использует первый из вышеназванных режимов,

кеш — сугубо железная штука и к ОС не имеет отношения. write-through обычно используется на мультипроцессорных (и мультиядерных, если кеш не общий) системах, чтобы кеши не были рассинхронизированы.

anonymous
()
Ответ на: комментарий от Agent666

Странно, что во всех видимых мною бенчмарках памяти запись гораздо медленнее чтения.

stassats ★★★★
()
Ответ на: комментарий от Svoloch

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

stassats ★★★★
()
Ответ на: комментарий от anonymous

> кеш — сугубо железная штука и к ОС не имеет отношения однако ОС может управлять стратегиями кэширования фрагметов физического адресного пространства

rei3er
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.