我用 C 语言开发了这个函数来读取每行一个单词组成的文件,就像标准的单词列表一样。 该功能已经得到了合理的优化,但我想知道是否有办法使用 OpenMP 并行化文件读取过程。我尝试了各种方法,但找不到可行的解决方案。
我的想法是在线程之间划分任务,以便每个线程使用一个私有数组来存储它读取的单词,然后将这些单词并行合并到输出数组(在主函数中使用)中。然而,我未能成功实施这种方法。 我的问题有可能的解决方案吗? 这是该函数的代码:
int file_read(const char *filename, unsigned char (*output)[MAX_WORD_LENGTH]) {
int fd = open(filename , O_RDONLY);
if ( fd < 0 ){
printf("Errore nella lettura del file\n");
perror("fd < 0");
exit(1);
}
// dimensione file in byte
off_t file_size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
// Mappiamo il file in memoria
char *file_data = (char *) mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
//mmap funzione che permette di mappare in memoria il file
//NULL significa che decide l'os dove metterlo
//file_size quanto è grande, calcolato prima con lseek
//PROT_READ dice che il file è solo in lettura
//MAP_PRIVATE privata al processo, alternativamente MAP_SHARED
//fd file descriptor
//0 dove iniziare a leggere il file, 0 = inizio
if (file_data == MAP_FAILED) {
perror("Errore nella mappatura del file");
close(fd);
exit(1);
}
close(fd);
int num_words = 0;
int i=0, temp_len=0;
char tempChar;
while ( i < file_size && num_words < MAX_WORDS ){
tempChar = file_data[i];
if(tempChar=='\n'){
if(temp_len <= MAX_WORD_LENGTH){
if(temp_len > 0){
output[num_words][temp_len]='\0';
temp_len = 0;
num_words++;
}
}
else{
printf("Parola troppo grande");
exit(1);
}
}
else if(tempChar!='\r'){
output[num_words][temp_len++]=tempChar;
}
i++;
}
//rilascio la memoria su cui era inserito il file
munmap(file_data, file_size);
return num_words;
}
附注该代码旨在读取大量数据,例如一百万个单词,在我的例子中,单词的最大长度为 56。 谢谢。
如果我正确理解你的问题,你想并行化从文件中读取单词的过程。
虽然并行执行多个文件很简单,但我将重点关注并行读取单个文件。
我建议将问题分为两个阶段:
获取有效Chunk:(单线程/主线程)
i
的终点和线程 i+1
的起点。重写While循环:(多线程)
此外,我建议使用树结构,例如AVL-Tree,其中线程可以直接插入到目标结构中,合理的访问时间为 O(log(n))。您可以使用单词作为键,使用出现次数作为值。如果该单词已经存在,只需添加计数即可;否则,创建一个新节点。
为了提高效率,我建议使用互斥体来修改树,以便线程一次写入一个。如果您有足够的 RAM,为每个节点创建一个互斥锁以及值可能会很有趣,从而允许并行插入而不降低性能。这可能会创建具有相同密钥的多个节点,但您可以在算法结束时通过遍历所有节点 (O(n)) 并对内容求和来合并它们。
如果您喜欢简单的列表/数组,请再次遍历树并将节点线性化为列表/数组(可能删除互斥体)。
我希望这能给你一个好主意!