PDA

View Full Version : [C o Java] Accesso ad un file (rw) in parallelo


fbcyborg
27-11-2010, 10:44
Salve a tutti,

premetto che secondo me non si può fare, ma non avendone la certezza chiedo anche a voi.
Vorrei poter leggere/scrivere un file in parallelo. Mi spiego con un esempio.
Un file lungo 2050 byte, verrebbe "suddiviso logicamente" in N parti uguali, dove N è il numero di Thread. Supponiamo che N sia pari a 4, allora la suddivisione sarebbe:
T0: Start: 0; Stop: 511.
T1: Start: 512; Stop: 1023.
T2: Start: 1024; Stop: 1535.
T3: Start: 1536; Stop: 2049.
(L'ultimo thread prende anche eventuali blocchi in surplus, qualora la dimensione del file non fosse multiplo di N.

Quindi, lo stesso file, verrebbe aperto in lettura o in scrittura (a seconda del caso), da 4 thread in contemporanea, ed ogni thread scrive o legge solo ed esclusivamente il suo settore. È tecnicamente possibile fare una cosa del genere (dare in pasto a più processi/thread lo stesso file, per poter parallelizzare l'operazione di scrittura/lettura).

Nel frattempo mi è venuto in mente il sistema di download parallelo di un file, ma in quel caso credo sia diverso.

banryu79
29-11-2010, 09:33
Le informazioni contenute in questa vecchia discusisone potrebbero esserti utili, in particolare il post di gugoXX:
- http://www.hwupgrade.it/forum/showthread.php?t=1771038

fbcyborg
29-11-2010, 10:38
Grazie,

premesso che nel frattempo mi era venuta in mente un'altra cosa ancora, le informazioni su quel thread mi hanno rinfrescato la memoria, ed in effetti mi ci ritrovo perfettamente con quei concetti.
Quello a cui pensavo, dunque, era appunto il fatto che in genere per migliorare le prestazioni in lettura/scrittura si può utilizzare un'architettura RAID 0, ad esempio. Avevo quindi considerato anche i problemi dovuti al saltellamento della testina avanti e indietro. Grazie di nuovo.

¥ Brutus ¥
29-11-2010, 15:17
Non vorrei contraddirvi, ma sono abbastanza certo che la tua idea sia più che sensata: il discorso della lettura fisica dei dati da parte della testina del disco rigido non è del tutto corretto, oggigiorno le architetture dei calcolatori sono talmente complesse che bisogna prendere in considerazione tantissimi aspetti differenti.
So con certezza che si ottiene un vantaggio, ma non saprei quantificartelo: cercherò di far intervenire in questa discussione un mio collega che ne sa più di me.

A presto!

banryu79
29-11-2010, 15:20
So con certezza che si ottiene un vantaggio, ma non saprei quantificartelo: cercherò di far intervenire in questa discussione un mio collega che ne sa più di me.

Sarebbe interessante :)

_Kratos_
29-11-2010, 20:56
@Brutus
Salve collega! :) è da molto che non scrivo qui

@fbcyborg
per quanto riguarda l'accesso multiplo in un file da parte di più thread della CPU non mi è mai venuto in mente di provare a farlo, però so che la CPU gestisce un thread alla volta quindi dubito che può fare 2 cose in parallelo, a meno che tu non abbia un multicore, però in questo caso come ha detto l'altro utente la testina dell'HDD è sempre una, quindi non sono sicuro che lo faccia in parallelo. A meno che (sto pensando io) non carichi il file in RAM (facendo una per esempio "int lunghezza = lseek(fd, 0, SEEK_END)" per vedere quanto è lungo il file, poi usando una "char c* = (char*)malloc(sizeof(char)*lunghezza)" per allocare la memoria necessaria (oppure facendo un array abbastanza lungo) e poi copiandoci dentro i caratteri tramite la "read(c,lunghezza)" ) e poi vedi se c'è qualche modo per accederci in parallelo con più thread, però purtroppo non ti saprei dire come.

P.S. mi sono dimenticato di chiederti se stai usando linux


Un metodo che invece funziona perché è quello che sto usando io per la mia tesi di laurea, è usare le librerie Nvidia CUDA con cui è possibile scrivere programmi che utilizzano migliaia di thread che accedono in parallelo ai dati che copiamo dentro la memoria video (o nelle altre memorie della GPU). che siano essi interi file o cose più piccole. Queste funzionano sia su windows che su linux ma bisogna avere una scheda con supporto CUDA. Se vuoi saperne di più scrivimi! :)

_Kratos_
29-11-2010, 21:01
Nel frattempo mi è venuto in mente il sistema di download parallelo di un file, ma in quel caso credo sia diverso.

in quel caso penso che si apra il file una sola volta e poi si fanno le scritture in parti diverse

fbcyborg
29-11-2010, 22:56
Ciao _Kratos_, grazie per l'intervento!
@fbcyborg
per quanto riguarda l'accesso multiplo in un file da parte di più thread della CPU non mi è mai venuto in mente di provare a farlo, però so che la CPU gestisce un thread alla volta quindi dubito che può fare 2 cose in parallelo, a meno che tu non abbia un multicore,Esatto, parti comunque dal presupposto che ho almeno un QuadCore, quindi minimo 4 thread. però in questo caso come ha detto l'altro utente la testina dell'HDD è sempre una, quindi non sono sicuro che lo faccia in parallelo.Ed infatti, anche questo è un pensiero che mi è venuto subito in mente. Non a caso, come dicevo, si usano architetture RAID anche per migliorare le prestazioni di lettura/scrittura. A meno che (sto pensando io) non carichi il file in RAM (facendo una per esempio "int lunghezza = lseek(fd, 0, SEEK_END)" per vedere quanto è lungo il file, poi usando una "char c* = (char*)malloc(sizeof(char)*lunghezza)" per allocare la memoria necessaria (oppure facendo un array abbastanza lungo) e poi copiandoci dentro i caratteri tramite la "read(c,lunghezza)" ) e poi vedi se c'è qualche modo per accederci in parallelo con più thread, però purtroppo non ti saprei dire come.Questa della malloc, è un'operazione che sicuramente farei, prima di portare un file in memoria, però la parallelizzazione andrebbe fatta (ovviamente se e solo se è un'operazione fattibile e intelligente), nel fetch da disco. Ma qui ovviamente ci sono una serie di fattori che giustamente sono stati presi in considerazione sia qui, ma soprattutto nella discussione citata nel secondo post.

P.S. mi sono dimenticato di chiederti se stai usando linuxHehe.. mi sono dimenticato io di dirlo. Oramai ragiono solo in un verso! :D Uso Linux :cool:


Un metodo che invece funziona perché è quello che sto usando io per la mia tesi di laurea, è usare le librerie Nvidia CUDA con cui è possibile scrivere programmi che utilizzano migliaia di thread che accedono in parallelo ai dati che copiamo dentro la memoria video (o nelle altre memorie della GPU). che siano essi interi file o cose più piccole. Queste funzionano sia su windows che su linux ma bisogna avere una scheda con supporto CUDA. Se vuoi saperne di più scrivimi! :)
Mmmh... molto interessante questa cosa!
Costano molto queste schede?

Grazie mille!

_Kratos_
29-11-2010, 22:59
L'elenco delle schede compatibili con CUDA le trovi sul sito della Nvidia. Mi sembra che la più economica sia la Geforce 8400 che oramai costa pochissimo. Ma precisamente a cosa ti serve fare questo lavoro con i files??

fbcyborg
29-11-2010, 23:02
La mia dovrebbe essere supportata, ho una GeForce 9400 GT.
Ho controllato adesso infatti.

Il lavoro che sto facendo è una ricerca a scopi di tesi di laurea, sarebbe un po' lunga da spiegare, ma l'obiettivo è di caricare file in memoria il più velocemente possibile per poi cifrarli, e/o decifrarli in parallelo (questo riesco a farlo), ma il collo di bottiglia sta proprio nel fetch dei file da disco.

¥ Brutus ¥
29-11-2010, 23:33
Un metodo che invece funziona perché è quello che sto usando io per la mia tesi di laurea, è usare le librerie Nvidia CUDA con cui è possibile scrivere programmi che utilizzano migliaia di thread che accedono in parallelo ai dati che copiamo dentro la memoria video (o nelle altre memorie della GPU), che siano essi interi file o cose più piccole.



Se si ottengono buoni risultati con migliaia di thread usando CUDA non dovrebbe esserci un qualche miglioramento (anche minimo) con le architetture multicore e/o multiprocessor?

Adesso che ci penso, comunque, magari potrebbe aiutarti una cosa: la funzione mmap() permette di mappare i file in memoria, così da poterli utilizzare come se fossero dei normali array di caratteri (senza necessità di ricorrere alla lseek().
Forse potresti ottenerne dei vantaggi, se non in termini di prestazioni almeno in termini di semplicità del codice da scrivere.
Spero che questo ti possa essere di aiuto!

fbcyborg
29-11-2010, 23:47
Giusto, conoscevo la funzione mmap(). Non c'avevo pensato però. Sicuramente approfondirò la cosa. Al momento comunque sto lavorando in Java.

Per quanto riguarda CUDA, mi si è aperto un nuovo mondo. Ho già cominciato a documentarmi, e ad installare toolkit e sdk. Ora sto cercando di capire come usare JCuda.

Una domanda: ma perché si parla di migliaia di thread? io vedo che la mia GPU viene rilevata con 16 core. Mettendone migliaia, penso che si otterebbe un effetto contrario. Dico questo perché ho provato a mandare in esecuzione una cifra come 256mila thread su 4 cpu, ed ho avuto un risultato molto brutto (ovviamente). Poi magari per la GPU è diverso, ma non saprei.

Per rispondere a ¥ Brutus ¥: certamente, già usando il multithreading sui core della CPU si ottengono dei miglioramenti di prestazioni non indifferenti.

Ah, altra domanda: sarebbe possibile usare sia i core della CPU (4) + quelli della GPU(16) per un totale di 20 nel mio caso? Così farei un multithreading con 20 operazioni in parallelo.

WarDuck
30-11-2010, 11:27
Sfruttare la GPU è consigliabile solo se il problema che devi risolvere si adatta in qualche modo all'architettura della GPU stessa, tipicamente si tratta di problemi altamente parallelizzabili (penso che la cifratura possa essere uno di questi).

Detto ciò ho i miei dubbi sul fatto che l'accesso ad un singolo disco meccanico possa essere parallelizzato, è risaputo infatti che l'accesso sequenziale alle informazioni su questi dischi è molto più rapido che l'accesso casuale.

Se posso darti un consiglio magari prova a deframmentare il file in questione.

In java usi il BufferedReader?

banryu79
30-11-2010, 12:02
In java usi il BufferedReader?

E se invece del package java.io usasse in package java.nio?
Penso ad esempio a java.nio.MappedByteBuffer... resta il fatto che questa classe lavora con un file mappato in memoria.
Non me ne intendo di operazioni a basso livello, ma la prima lettura fisica del fie dal disco, se questo non è ancora stato caricato in memoria, ha ben poco di parallelizzabile... giusto?

¥ Brutus ¥
30-11-2010, 12:46
Sì, l'idea è che non sia parallelizzabile, ma io non lo darei per scontato: l'uso delle pipeline potrebbe incrementare le prestazioni anche per la lettura da disco (benché l'operazione in sé non sia parallelizzabile).
Comunque penso che sia più opportuno utilizzare file mappati in memoria, grazie al Direct Memory Access che velocizza l'operazione, da quel momento in poi sfrutti tutta la capacità computazionale che vuoi!

fbcyborg
30-11-2010, 13:41
In java usi il BufferedReader?
In realtà sto usando una libreria (http://wizard4j.org/) che implementa un metodo File2String (http://wizard4j.org/doc/javadoc/index.html?org/wizard4j/util/File2String.html). Analizzando il codice sorgente, poi mi sono reso conto che non fa nulla che non mi sarebbe venuto in mente di fare, ovvero usare BufferedReader.
Ecco la classe:

/*
* Copyright (c) 2009 Dirk Ooms
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.wizard4j.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class File2String {
private static Logger logger = LoggerFactory.getLogger(File2String.class);

/**
* @param fileName
* @return content of file
*/
public static String getFileContent(String fileName) {
File file = new File(fileName);
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(
file));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
buffer.append(line);
buffer.append("\n");
}
return buffer.toString();
} catch (Exception e) {
logger.error("File {} not found: {}", file.getName(), e
.getMessage());
return null;
}

}
}

_Kratos_
30-11-2010, 14:09
Una domanda: ma perché si parla di migliaia di thread? io vedo che la mia GPU viene rilevata con 16 core. Mettendone migliaia, penso che si otterebbe un effetto contrario. Dico questo perché ho provato a mandare in esecuzione una cifra come 256mila thread su 4 cpu, ed ho avuto un risultato molto brutto (ovviamente). Poi magari per la GPU è diverso, ma non saprei.


se non sbaglio la tua scheda ha 2 multiprocessori con all'interno 8 core ciascuno (giusto?). Sappi che ogni multiprocessore supporta 768 threads :) quindi in totale ne puoi creare 1536. mentre le schede con compute capability 2.0 (cioè quasi le ultime uscite) ne supportano 1024 per ogni multiporcessore (lo trovi scritto nelle guide che ti puoi scaricare dal sito, in uno degli appendici mi sembra).

però come avrai capito questi thread non fanno il fetch dall'hdd in parallelo, ma lavorano all'interno della gpu quindi prima dovrai caricare normalmente il file e poi una volta caricato nella memoria della gpu crei i thread e fai quello che devi fare.

Cmq io sto usando C-cuda, con Java non ho mai provato

_Kratos_
30-11-2010, 14:17
Ah, altra domanda: sarebbe possibile usare sia i core della CPU (4) + quelli della GPU(16) per un totale di 20 nel mio caso? Così farei un multithreading con 20 operazioni in parallelo.

si mentre la gpu lavora puoi fare altre cose con i thread della cpu (possibilmente delle cose indipendenti, dato che non è cosi immediato farli comunicare poi)

fbcyborg
30-11-2010, 14:30
Sì sono 2 multiprocessori da 8 core ciascuno. Ovviamente questa cosa dei 768 thread vale solo per le GPU, immagino.
Per quanto riguarda il problema del fetch del file da disco, ok.. ad ogni modo ora volevo provare a usare i core della GPU per fare la decrittazione. Poi magari al limite, posso anche pensare di sfruttarli per il fetch da disco.
Ma solo una volta che ho capito come si usa questo cuda.

_Kratos_
01-12-2010, 14:13
si per la decrittaziono va bene, carichi il file nella VRAM e poi lo elabori con i vari threads. però i threads della gpu non possono accedere direttamente all'hdd per fare il fetch, possono accedere al massimo alla RAM del computer (usando la Page-locked mapped memory... lo trovi sempre nella guida Nvidia), quindi non ti possono aiutare per il fetch.

fbcyborg
01-12-2010, 14:21
OK, ti ringrazio.

Intanto sto scrivendo del codice C, del corrispettivo che ho fatto in Java, e poi vedrò il da farsi!

fbcyborg
07-12-2010, 22:39
Salve di nuovo!

Allora, ho appena finito di sviluppare il mio software, usando un numero di thread = numero Core, nel modo classico, in C.
Ora vorrei sfruttare la tecnologia CUDA per fare le operazioni che svolgo in parallelo già in modalità multithread classica.

Da dove posso iniziare? Stavo cercando degli esempi di codice C che usano CUDA.
Per ora ho trovato questo (http://people.maths.ox.ac.uk/~gilesm/hpc/NVIDIA/NVIDIA_CUDA_Tutorial_No_NDA_Apr08.pdf), che sembra molto interessante.

_Kratos_
09-12-2010, 14:11
non mi ero accorto che avevi fatto un altra domanda :)

sul sito della nvidia c'è il "CUDA C best practice guide" e la "CUDA programming guide" in cui spiega alcune cose e fa alcuni esempi di codice (oltrea al "reference manual" che sarebbe la documentazione delle librerie). In giro ho trovato anche delle slide di un corso su CUDA che tengono all'università di Stanford, e altre slide dal sito di un corso simile al MIT (Massachusetts Institute of tecnology).
corso del MIT: http://sites.google.com/site/cudaiap2009/
corso Stanford: http://stanford-cs193g-sp2010.googlecode.com/svn/trunk/lectures/
e anche http://code.google.com/p/stanford-cs193g-sp2010/
altro corso ancora: http://people.maths.ox.ac.uk/gilesm/cuda/

se fai altre ricerche troverai sicuramente altre cose.
se ti serve aiuto puoi anche chiedere sul forum ufficiale di nvidia cuda.

Se sei interessato all'acquisto di un libro invece c'è "CUDA by examples" e "Programming massive parallel multiprocessor". Il secondo ce l'ho e mi è stato molto utile, spiega molto bene tutti i concetti.

fbcyborg
09-12-2010, 23:37
non mi ero accorto che avevi fatto un altra domanda :)
LOL, mi sa che non hai le notifiche via email attive! :)

Grazie per le indicazioni. Intanto stavo spulciando il manuale "CUDA by examples". Questo ce l'ho già ed ho visto diverse cose interessanti! :)

_Kratos_
10-12-2010, 00:41
Cuda by examples ce l'hai in pdf o l'hai comprato??

fbcyborg
10-12-2010, 09:58
PDF

_Kratos_
10-12-2010, 16:02
facciamo a cambio? :D io ti mando "programming massive parallel multiprocessor"

fbcyborg
10-12-2010, 16:09
Ahaha! LOL :D

_Kratos_
11-12-2010, 17:37
ops, si chiama "programming MASSIVELY parallel PROCESSOR", non multiprocessor :)