Вход на сайт
Вопрос по С
NEW 14.10.04 00:21
Написал на практике две маленькие программки, надо было создать аrray 8MB,a потом совершать над каждым элементом какую нибудь операцию (неважно какую). Один раз надо создать local array во второй раз global array, потом написать в чем между программами разница... Я абсолютно ничего не заметил, CPU грузится одинаково, как в первом, так и во втором варианте, память тоже одинаково загружается.. Не подскажите в чем могут быть еще различия?
Привожу код:
Привожу код:
#include <stdio.h>
int main(void)
{
long wert=0;
int i=0;
long array[2097152];
while(i<2097152)
{
array[i ]=wert;
i++;
}
while(i>0){
array[i ]=array[i ]+1;
array[i ]=array[i ]-1;
i--;
}
return 0;
}
____________________________________
#include <stdio.h>
long array[2097152];
int main(void)
{
long wert=0;
int i=0;
while(i<2097152)
{
array[i ]=wert;
i++;
}
while(i>0){
array[i ]=array[i ]+1;
array[i ]=array[i ]-1;
i--;
}
return 0;
}
NEW 14.10.04 00:41
в ответ NevеrMind 14.10.04 00:37
Вот его задание:
3.2 p_mem, ein rechenintensives Programm mit großem Hauptspeicherbedarf
Realisiert durch ein großes Array von 8 MB, in dem in einer Schleife alle Elemente verändert werden.
Beobachten Sie den Unterschied zwischen einem lokal und einem global deklarierten Array. (Deklaration innerhalb bzw. außerhalb main)
Тут явно какая то разница должна быть...
3.2 p_mem, ein rechenintensives Programm mit großem Hauptspeicherbedarf
Realisiert durch ein großes Array von 8 MB, in dem in einer Schleife alle Elemente verändert werden.
Beobachten Sie den Unterschied zwischen einem lokal und einem global deklarierten Array. (Deklaration innerhalb bzw. außerhalb main)
Тут явно какая то разница должна быть...

NEW 14.10.04 01:02
>А не можешь обьяснить почему локальный рушит, а глобальный нет?
Выскажу предположение, что под сегмент стека (там будет локальный массив лежать) отводится гораздо меньше 8Мб, а под сегмент данных (там будет глобальный массив), больше. Точные цифры не знаю, т.к. это ОС специфично, но, скорее всего, именно так.
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Выскажу предположение, что под сегмент стека (там будет локальный массив лежать) отводится гораздо меньше 8Мб, а под сегмент данных (там будет глобальный массив), больше. Точные цифры не знаю, т.к. это ОС специфично, но, скорее всего, именно так.
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Dropbox - средство синхронизации и бэкапа файлов.
NEW 14.10.04 08:50
в ответ voxel3d 14.10.04 01:02
Все правильно. Помимо переполнения стека могут быть и другие неприятности.
Если большой массив объявлен в функции, которая часто вызывается (main() вызывается только один раз), то память под массив выделяется в стеке при каждом вызове ф-ции (и освобождается потом). Это может привести к проблемам с производительностью, если даже стек и не переполнится.
А если представить себе пример рекурсивной ф-ции с таким большим локальным массивом...
Если большой массив объявлен в функции, которая часто вызывается (main() вызывается только один раз), то память под массив выделяется в стеке при каждом вызове ф-ции (и освобождается потом). Это может привести к проблемам с производительностью, если даже стек и не переполнится.
А если представить себе пример рекурсивной ф-ции с таким большим локальным массивом...
NEW 14.10.04 09:35
в ответ Gaidzin 14.10.04 08:50
>Это может привести к проблемам с производительностью, если даже стек и не переполнится.
Кстати, чисто теоретически, если б стек не переполнялся.. потери производительности не было бы. С чего бы ей взяться? Резервируется кусок стека под массив одним махом. Что один байт под него резервировать, что 8 мегабайт. Память-то не инициализируется.
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Кстати, чисто теоретически, если б стек не переполнялся.. потери производительности не было бы. С чего бы ей взяться? Резервируется кусок стека под массив одним махом. Что один байт под него резервировать, что 8 мегабайт. Память-то не инициализируется.
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Dropbox - средство синхронизации и бэкапа файлов.
NEW 14.10.04 10:43
в ответ voxel3d 14.10.04 09:35
Да, вероятно, я не прав насчет производительности. В самом деле с точки зрения производительности без разницы смещен ли указатель стека на 1 байт или на несколько МБ.
Ну тогда остается рекурсия. Если уж одиночный вызов ф-ции с локальным массивом не переполнит стек, то рекурсивная ф-ция с большим объемом локальных данных может убить любой стек...
Да, кстати, первый примерчик под windows обрушается аварийно, а под linux нет. Неужели под linux стек имеет такой большой размер? Кто знает?
Ну тогда остается рекурсия. Если уж одиночный вызов ф-ции с локальным массивом не переполнит стек, то рекурсивная ф-ция с большим объемом локальных данных может убить любой стек...
Да, кстати, первый примерчик под windows обрушается аварийно, а под linux нет. Неужели под linux стек имеет такой большой размер? Кто знает?
NEW 14.10.04 16:20
>массив на 8 мб с элементами типа long сожержит 2048 элементов,а не 2097152;-)
Если принять, что в long 4 байта, то:
1Мб = 1024б * 1024б = 1048576б
8Мб = 1048576б * 8 = 8388608б
array_size = 8Мб / 4 = 8388608 / 4 = 2097152
Как 2048 получется, не пойму?
>Размер для long - 32 бита,или что говорит sizeof(long)
На конкретной платформе для конкретного компилятора..
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Если принять, что в long 4 байта, то:
1Мб = 1024б * 1024б = 1048576б
8Мб = 1048576б * 8 = 8388608б
array_size = 8Мб / 4 = 8388608 / 4 = 2097152
Как 2048 получется, не пойму?
>Размер для long - 32 бита,или что говорит sizeof(long)
На конкретной платформе для конкретного компилятора..
---
Идиотов и фриков перевоспитать НЕВОЗМОЖНО!!!
Dropbox - средство синхронизации и бэкапа файлов.
NEW 14.10.04 17:19
Извиняюсь за свой кривой код,в С не силен(ещё)
#include <stdio.h>
#define N 2097152
void main()
{
long * array;
array=(long *)malloc(sizeof(long)*N,0);
int i;
for (i=0;i<N;i++)
array[i ]=i;
free(array,0);
}
в таком виде у меня программа работает,массив инициализируется.
Вопрос.Как объявить указатель на блок памяти глобально?Если это возможно.
Среднее время выполнения
time ./ger1
real 0m0.042s
user 0m0.017s
sys 0m0.006s
#include <stdio.h>
#define N 2097152
void main()
{
long * array;
array=(long *)malloc(sizeof(long)*N,0);
int i;
for (i=0;i<N;i++)
array[i ]=i;
free(array,0);
}
в таком виде у меня программа работает,массив инициализируется.
Вопрос.Как объявить указатель на блок памяти глобально?Если это возможно.
Среднее время выполнения
time ./ger1
real 0m0.042s
user 0m0.017s
sys 0m0.006s
NEW 14.10.04 17:32
в ответ voxel3d 14.10.04 01:02
Вот что я вычитал в нете про локальный array:
First, this allocates the array on the stack, which has a very limited size on most operating systems (declaring an array with more than a few thousand elements will often cause a crash).
теперь немного поясняется
First, this allocates the array on the stack, which has a very limited size on most operating systems (declaring an array with more than a few thousand elements will often cause a crash).
теперь немного поясняется

NEW 14.10.04 17:50
в ответ Chipolino 14.10.04 15:20
У меня мелькала мысль, что возможно имелось разница в распределении памяти. Но обе программы отработали без проблем. Каким образом "на глаз" можно заметить какую либо разницу? Неправильное задание какое-то.
---
Майкл Дудикофф в фильме "Он и микробы убивает!" (2:5020/720.10)
---
Майкл Дудикофф в фильме "Он и микробы убивает!" (2:5020/720.10)
NEW 14.10.04 17:57
в ответ Russman 14.10.04 17:50
В ответ на:У меня мелькала мысль, что возможно имелось разница в распределении памяти. Но обе программы отработали без проблем. Каким образом "на глаз" можно заметить какую либо разницу? Неправильное задание какое-то.
Я повторюсь,но первая программа у меня вылетает с "segmentation fault"