powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как в многопоточной программе ПЕРЕвыделять память?
25 сообщений из 101, страница 4 из 5
Как в многопоточной программе ПЕРЕвыделять память?
    #39559765
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока вы не поубивали друг друга, замечу, что контейнеры позволяют резервировать память, сводя число realloc-ов к минимуму.
оффтопвспоминается история из прошлого века, когда я был молодым и зелёным , мы делали вдвоём софт для некого девайса в НИИ, я делал пользовательскую часть, с кучей графиков. Делалось всё на LabView, у которой тогда уже были нормальные контейнеры (в STL они уже тоже были) встроенные прямо в средства построения графиков. Так вот, я по ходу поступления данных добавлял их в массив графика. Всё было ок, но через некоторое время учёные пожаловались на тормоза. Я загрустил, а мой более умный напарник даже не глядя в "код", сразу сказал, что я не сделал резервирование памяти, а компонент графика на каждое добавление делает realloc, что на уже на нескольких десятках тысяч записей становится заметно.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39559968
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockBasil A. SidorovНу или берём готовое из boost/stl.
Ни в одном из этих случаев не возникает нужда в realloc.
Я ж говорю, мне надоело. Заходим в исходники std::vector или TList или не знаю, что там в java, видим там realloc и пишем письмо о том, что его использование нецелесообразно разработчикам - в Microsoft, Oracle, Idera и т.д.
Мне писать уже ничего не надо, мне всё понятно.

std::vector не может использовать С-шный realloc, поскольку оперирует не только с POD-структурами, а также использует аллокаторы.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39559976
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLНе думаю, что сам С/С++ внутри себя реализует стандартные функции. Для этого используются отдельные библиотеки, которые подключаются в программу с помощью директив препроцессору #include. И вот именно эти реализации библиотек определяют возможность многопоточной работы (а не факт запуска компиляции с какими- либо ключами).

Например, по вашей ссылке видно, что malloc требует библиотеки <stdlib.h>.Никакие библиотеки с помощью директивы препроцессора #include в сборку не включаются. Включение библиотек указывается отдельно компилятору (обычно с помощью аргумента командной строки). Стандартные библиотеки Си и C++ могут быть не только библиотеками динамической линковки времени выполнения (runtime), но и статическими - слинкованными полностью с самим исполняемым файлом программы (к примеру, у "гнуса" есть параметры командной строки "-static-libgcc" и "-static-libstdc++").
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39559982
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТак и не понял: под всеми ОС QT- программа, исползующая malloc, realloc и free, будет работать корректно?

А что насчет memcpy?

НЕ БУДЕТ потокобезопасна.
В том смысле, что с одной памятью в разных потоках оперировать ею нельзя.Оперировать-то можно, но программу придется писать с учётом барьеров компилятора и кэша процессора.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39559984
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglНикто не забыл, что память выделяется страницами, да еще и с виртуализацией страниц?

Пока в странице, вообще нет проблем расшириться.

А если нет - то дописать процессору в табличку аллокаций VM линейное расширение (я не настолько ос разработчик, но АФАИК, это тоже небольшая проблема)Это она для кучи выделяется страницами, а кучей заведует библиотечный менеджер памяти из стандартной либы, который может на одной странице выделять блоки для разных потоков.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39559996
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov~секунда на "почти миллион страниц" - вполне нормальный результат.А ты уверен, что современная 64-битная операционная система выделяет JVM'у страницы именно по 4кБ, а не по 4Мб?
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560005
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
https://msdn.microsoft.com/ru-ru/library/dd335933.aspx Так же, как и в Win32, размер страницы на платформе x64 равен 4 Кб.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560041
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T https://msdn.microsoft.com/ru-ru/library/dd335933.aspx Так же, как и в Win32, размер страницы на платформе x64 равен 4 Кб.Спасибо, почитал.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560076
вЪю
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

очень старая статья. Я совсем не специалист в виндовс но даже мне понятно что виндовс 10 должна использовать двухмегабайтные странички. Иначе микрософту никогда недагнать линух.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560179
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вЪюDima T,

очень старая статья. Я совсем не специалист в виндовс но даже мне понятно что виндовс 10 должна использовать двухмегабайтные странички. Иначе микрософту никогда недагнать линух.
А в линуксе они двухмегабайтные?
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560180
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного про споры выше про realloc(): не думаю что realloc() без копирования обходится, но в виндовсе есть HeapReAlloc() , а вот здесь уже средства ОС, т.е. перемещение и довставка страниц, вместо копирования. Если кому очень надо, то можно воспользоваться.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560182
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tне думаю что realloc() без копирования обходится
Думать не надо. Достаточно произвести тест на 3 строки кода.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560183
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovYuRockДа, нажми ctrl+f в открывшемся по своей ссылке, набери в строке поиска reallocВы точно смотрели, что делают все эти realloc-и?
Подсказка: наберите в строке поиска "alloc("
Ок, именно в Вашем спец-примере я не нашел "alloc(". Всё, значит, считайте, что я не прав. Копируйте память всегда и дальше. Хотя понятное дело, что перевыделение памяти происходит где-то в недрах, в base::resize... но искать я не намерен, не вижу смысла что-то доказывать.
Считаете, что vector всегда тупо копирует память при необходимости увеличения изначально зарезервированного массива указателей? Ок, я не спорю.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560184
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv std::vector не может использовать С-шный realloc, поскольку оперирует не только с POD-структурами, а также использует аллокаторы.
Угу. Какой-то магический, другой менеджер памяти, в котором нет и не нужен realloc. Хорошо.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560186
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockDima Tне думаю что realloc() без копирования обходится
Думать не надо. Достаточно произвести тест на 3 строки кода.
Давай ссылку на тест из 3 строк.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560195
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TYuRockпропущено...

Думать не надо. Достаточно произвести тест на 3 строки кода.
Давай ссылку на тест из 3 строк.
На тебе ссылку
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
#include <stdio.h>
#include <windows.h>

#define TEST_SIZE ( 1024 * 1024 * 512 )

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
	char cText[ 50 ];
	void *p, *np;
	DWORD dwStart, dwTime;

	p = malloc( TEST_SIZE );

	dwStart = GetTickCount();
	np = realloc( p, TEST_SIZE + 1 );
	dwTime = ( DWORD ) ( GetTickCount() - dwStart );

	free( p );

	if( np )
		sprintf( cText, "realloc time: %d", dwTime );
	else
	  sprintf( cText, "realloc returns NULL" );

	MessageBox( 0, cText, "", 0 );

	p = malloc( TEST_SIZE );

	dwStart = GetTickCount();
	np = malloc( TEST_SIZE + 1 );
	memcpy( np, p, TEST_SIZE );
	free( p );
	dwTime = ( DWORD ) ( GetTickCount() - dwStart );

	free( np );

	sprintf( cText, "alloc/memcpy/free time: %d", dwTime );
	MessageBox( 0, cText, "", 0 );

	return 0;
}


1-й MessageBox показывает "realloc time: 0", 2-й - ~2000 миллисекунд. Это на моём компе.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560202
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devА ты уверен, что современная 64-битная операционная система выделяет JVM'у страницы именно по 4кБ, а не по 4Мб?Ну, если не касаться совсем гигантских страниц, то, насколько мне известно:
1. По два мегабайта, а не по четыре;
2. Чтобы запросить у системы именно большие страницы требуется несколько предусловий, поэтому:
2.1. По умолчанию всегда выделяются четырёхкилобайтовые страницы;
2.2. Для работы с большими страницами есть отдельная опция комстроки, которая может быть проигнорирована системой;

А действуют все эти ограничения потому, что у больших страниц чёткая и достаточно узкая область - работа с большими объёмом физической памяти.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560211
вЪю
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockMasterZiv std::vector не может использовать С-шный realloc, поскольку оперирует не только с POD-структурами, а также использует аллокаторы.
Угу. Какой-то магический, другой менеджер памяти, в котором нет и не нужен realloc. Хорошо.
нет и ненужен std::allocator .
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560213
вЪю
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TвЪюDima T,

очень старая статья. Я совсем не специалист в виндовс но даже мне понятно что виндовс 10 должна использовать двухмегабайтные странички. Иначе микрософту никогда недагнать линух.
А в линуксе они двухмегабайтные?
в glibc стандартном аллокаторе - нет.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560215
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вЪюнет и ненужен
Ну не нужен так не нужен.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560243
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чисто приколоться
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
public class test {
  private static int size = 0;
  private static int[] source = null, target = null;
  private static Runtime rt = Runtime.getRuntime();

  private static int[] alloc(int[] buffer, int size) {
    long start = System.nanoTime();
    buffer = new int[size];
    System.out.print(" Alloc " + (4L * buffer.length + 512*1024)/1024/1024 + " Mb in ");
    System.out.println((System.nanoTime() - start + 512*1024)/1024/1024 + " ms");
    return buffer;
  }

  private static void copy(int[] source, int[] target) {
    long start = System.nanoTime();
    System.arraycopy(source,0, target,0, source.length);
    System.out.print("  Copy " + (4L * source.length + 512*1024)/1024/1024 + " Mb in ");
    System.out.println((System.nanoTime() - start + 512*1024)/1024/1024 + " ms");
  }

  private static void stat() {
    System.out.print("Memory: " + (rt.totalMemory() + 512*1024)/1024/1024 + " Mb total / ");
    System.out.println((rt.freeMemory() + 512/1024)/1024/1024 + " Mb free");
  }

  public static void main(String[] args) {
    try { size = Integer.parseInt(args[0]); }
    catch (RuntimeException e) {}
    finally {}
    if (size < 1) size = 512;
    if (size > 1024) size = 512;
    size *= 1024*1024;

    stat();
    source = alloc(source,size);
    target = alloc(target,size+1024*1024);
    copy(source,target);
    stat();
    System.out.println("");
  }
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
VM settings:
    Min. Heap Size: 3.50G
    Max. Heap Size: 3.50G
    Ergonomics Machine Class: client
    Using VM: Java HotSpot(TM) 64-Bit Server VM

Memory: 3435 Mb total / 3399 Mb free
 Alloc 1152 Mb in 140 ms
 Alloc 1156 Mb in 151 ms
  Copy 1152 Mb in 420 ms
Memory: 3435 Mb total / 1091 Mb free
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560254
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

Ну вот уже 700 мс, и еще приплюсовать сюда время на освобождение - оно далеко не мало. М это при достатке памяти.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560287
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНу вот уже 700 мс, и еще приплюсовать сюда время на освобождение - оно далеко не мало.Это Спарта Ява - встроенный (фоновый) сборщик мусора.
Но вы не понимаете главного: исключая специально подобранные случаи - невозможно воспользоваться "быстрым довыделением памяти" в реальной жизни .
Поэтому в реальной жизни никто не будет работать с одним куском "в размер доступной памяти" - создадут массив из блоков более адекватного размера и будут разносить данных по этим (суб)блокам.
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560291
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock1-й MessageBox показывает "realloc time: 0", 2-й - ~2000 миллисекунд. Это на моём компе.
Немного модифицировал тест
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
int main(int argc, char** argv[])
{
	DWORD dwStart, dwTime;
	void *p, *np;
	p = malloc(TEST_SIZE);

	dwStart = GetTickCount();
	np = realloc(p, TEST_SIZE + 100500);
	dwTime = (DWORD)(GetTickCount() - dwStart);
	
	printf("realloc() %d ms\n", dwTime);
	free(np);


	std::vector<char> v(TEST_SIZE);

	dwStart = GetTickCount();
	v.resize(TEST_SIZE + 100500);
	dwTime = (DWORD)(GetTickCount() - dwStart);

	printf("v.resize() %d ms\n", dwTime);
	return 0;
}


Результат
Код: plaintext
1.
realloc() 234 ms
v.resize() 172 ms
...
Рейтинг: 0 / 0
Как в многопоточной программе ПЕРЕвыделять память?
    #39560499
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovНо вы не понимаете главногоЯ вообще ничего не понимаю практически. При этом страх берет, когда подумаешь, что же тогда понимают те, кто со мной спорит/поучает.
...
Рейтинг: 0 / 0
25 сообщений из 101, страница 4 из 5
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как в многопоточной программе ПЕРЕвыделять память?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]