Jump to content

Melhor usar realloc ou resize


kaub0st3r
 Share

Recommended Posts

Pois o problema é que necessito mesmo de usar arrays dinâmicos, i.e. eu não queria usar o new[] porque o meu array está constantemente a variar e tanto posso ter um array de 1000 como ter um array de 100 milhões. Eu neste momento estou a usar realloc() e com instância pequenas até vai dando, o problema é com as gigantes.

blogue: migalhasfrog.blogspot.comtwitter: ricardo_pt

Link to comment
Share on other sites

A menos que os elementos do teu vector sejam muito pequenos, não vais ter memória para atingir os 100 milhões de elementos. Para essa quantidade entras no território da memória virtual. Convém teres presente que normalmente um 'resize' dum vector é feito copiando todo o conteúdo do vector para um com o novo tamanho; se fizeres isso muitas vezes o computador vai passar o tempo a fazer isso e se esgotares a memória física então... bem podes esperar sentado.

Se precisas mesmo de gerir vectores desse tamanho então não os uses; cria uma lista ligada de páginas de tamanho fixo, que levariam um número fixo de elementos. Sabendo que cada página levaria 'x' elementos seria fácil (e só ligeiramente mais lento do que vectores) determinar e localizar a página com o elemento pretendido. Quando a memória começar a escassear podes despejar páginas para um ficheiro em disco, substituindo a página na memória por uma com apenas um campo a indicar o 'offset' onde procurar a página em disco.

Link to comment
Share on other sites

Não sei o que consideras gigante mas podes nao ter memoria suficiente disponivel. Tens de meter uma verificação antes de utilizares memoria

Não sei se te referes a memoria fisica do meu pc, mas tem 8gb. como verifico?

A menos que os elementos do teu vector sejam muito pequenos, não vais ter memória para atingir os 100 milhões de elementos. Para essa quantidade entras no território da memória virtual. Convém teres presente que normalmente um 'resize' dum vector é feito copiando todo o conteúdo do vector para um com o novo tamanho; se fizeres isso muitas vezes o computador vai passar o tempo a fazer isso e se esgotares a memória física então... bem podes esperar sentado.

Se precisas mesmo de gerir vectores desse tamanho então não os uses; cria uma lista ligada de páginas de tamanho fixo, que levariam um número fixo de elementos. Sabendo que cada página levaria 'x' elementos seria fácil (e só ligeiramente mais lento do que vectores) determinar e localizar a página com o elemento pretendido. Quando a memória começar a escassear podes despejar páginas para um ficheiro em disco, substituindo a página na memória por uma com apenas um campo a indicar o 'offset' onde procurar a página em disco.

Por acaso tens algum link a explicar o uso de memoria virtual?

thanks a todos

blogue: migalhasfrog.blogspot.comtwitter: ricardo_pt

Link to comment
Share on other sites

Não precisas de fazer nada para usar memória virtual pois isso é controlado pelo SO. Imagina que tens 6 GB livres na tua máquina e começas a alocar blocos de 1 MB. Antes de atingires esses 6 GB o SO vai reparar que a memória começa a escassear e vai tentar despejar para disco (para o 'pagefile') blocos de memória pertencentes a outros programas. Quanto mais memória pedires mais blocos vai ele despejar, até que o espaço no 'pagefile' fique cheio (caso em que dá um erro de memória virtual demasiado pequena) ou até esgotares os ~8 GB (tirando o minimo indispensável para o SO). Durante estes despejos o computador ficará exponencialmente mais lento, pois existem sempre múltiplos processos a correr, que irão obrigar a voltar a carregar blocos do disco, criando uma 'swap storm' (quando a luz indicadora do disco está sempre acessa).

A memória virtual do SO deve ser encarada como uma rede de segurança, para evitar que um programa falhe por outros estarem a gastar demasiado memória e não como algo para usar livremente.

Link to comment
Share on other sites

Como acedes à memória? É sequencialmente (0,1,2,3...) ou acedes a várias posições(3,1,1000,...)?

No primeiro caso, usa lists. Deve resolver o teu problema.

No segundo caso, não faças realloc com a memória exacta que precisas.

O que te aconselho a fazer é o mesmo que o vector de C++ faz quando fazes push_back (penso que não faz isso quando usas o resize): Faz só realloc em potências de 2.

Ou seja, se quiseres 1000 dados, fazes um realloc de 1024, por exemplo. Assim não tens de fazer tantos reallocs (neste exemplo, podias adicionar 24 elementos ou retirar 488 elementos sem teres de fazer realloc). Obviamente perdes um bocado em memória, mas vai-te compensar muito em velocidade.

MIEIC @ FEUP

http://project557.blogspot.com/ --- Development Blog

Proteja a sua pen: http://lastknight.pt.vu

Link to comment
Share on other sites

Como acedes à memória? É sequencialmente (0,1,2,3...) ou acedes a várias posições(3,1,1000,...)?

No primeiro caso, usa lists. Deve resolver o teu problema.

No segundo caso, não faças realloc com a memória exacta que precisas.

O que te aconselho a fazer é o mesmo que o vector de C++ faz quando fazes push_back (penso que não faz isso quando usas o resize): Faz só realloc em potências de 2.

Ou seja, se quiseres 1000 dados, fazes um realloc de 1024, por exemplo. Assim não tens de fazer tantos reallocs (neste exemplo, podias adicionar 24 elementos ou retirar 488 elementos sem teres de fazer realloc). Obviamente perdes um bocado em memória, mas vai-te compensar muito em velocidade.

eu acedo sequencialmente

for (i=ktpos[k];i<ktpos[k+1];i++){
			ccolbeg[k]=(int *)realloc(ccolbeg[k],(ii+1)*sizeof(int));
			ccolbeg[k][ii]=kk;
			for(j=0;j<numrowsp[k];j++) {
				if (ktcplex[i] == indrowsp[j][1]) {
					ccolind[k]=(int *)realloc(ccolind[k],(kk+1)*sizeof(int));
					ccolval[k]=(double *)realloc(ccolval[k],(kk+1)*sizeof(double));
					ccolind[k][kk] = j;
					ccolval[k][kk] = 1;
					kk++;
				}
			}
			ccolind[k]=(int *)realloc(ccolind[k],(kk+1)*sizeof(int));
			ccolval[k]=(double *)realloc(ccolval[k],(kk+1)*sizeof(double));
			ccolind[k][kk] = numrowsp[k];
			ccolval[k][kk] = Area[ktcplex[i]];
			kk++;
			ccolcnt[k]=(int *)realloc(ccolcnt[k],(ii+1)*sizeof(int));
			ccolcnt[k][ii]=kk-contador;
			contador=kk;
			ii++;
		} 

vou experimentar as listas (nunca trabalhei com listas  🙂 )

obrigado  😄

blogue: migalhasfrog.blogspot.comtwitter: ricardo_pt

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.