如何用openmp转jpg2dicom?
How to use openmp to convert jpg2dicom?
我需要将数百张 jpg 图像转换为 dicom。我有一个 web 应用程序,这篇文章最初是用 Node.js 制作的,但速度很慢。我想在 C 中做并使用 openmp 并行化以下代码:
int main(){
DIR *dir;
struct dirent *arq;
dir = opendir("./jpg");
char cmd1[255] = "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/";
char cmd_aux[255] = "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/";
char buf[255];
char nomeArq[255];
int i;
//Stretch in which I use openmp
while ((arq = readdir(dir)) != NULL){
strncpy(nomeArq, arq->d_name, 255);
if(nomeArq[0] != '.'){
sprintf(buf, " dcm/imagem-%d.dcm", i);
strcat(cmd1, nomeArq); // cmd1 + nomeArquivo
strcat(cmd1, buf);
system(cmd1);
strncpy(cmd1, cmd_aux, 255);
}
i++;
}
closedir(dir);
return 0;
}
我怎么知道这段代码是 I/O 绑定的,我想问问是否真的不能用 openmp 获得任何加速。如果可能的话,如何在使用 openmp 时并行化这个循环。如果我不是很清楚,对不起!我还在学习英语!
Bash解决方案
首先,如果考虑现有工具,您的任务会更容易:
- GNU Parallel
xargs
带多进程参数
xargs
示例(来自 bash 命令提示符):
ls ./jpg | xargs -P 0 -i ./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/{} dcm/{}.dcm
OpenMP
使用 for
循环更容易,您可以开始将文件列表放入数组中(Whosebug code 了解如何操作)。
// put your code for reading he files list into an array //
int main() {
char **files;
const size_t count = file_list("./jpg", &files);
#pragma omp parallel for
for(size_t i=0;i<count;++i) {
if(files[i][0] == '.' ) { continue; } // 'skip' directory entry, maybe you should implement some better check ( extension, or even checking if it is a file at all)
// keep the buffer local to the loop
char *buf = malloc(1024);
// already calling sprintf, use it for building the whole command line, and avoid the strncpy & strcat
sprintf(buf, "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/%s dcm/imagem-%zu.dcm",files[i],i);
system(buf);
free(buf); // cleanup
}
return EXIT_SUCCESS;
}
我需要将数百张 jpg 图像转换为 dicom。我有一个 web 应用程序,这篇文章最初是用 Node.js 制作的,但速度很慢。我想在 C 中做并使用 openmp 并行化以下代码:
int main(){
DIR *dir;
struct dirent *arq;
dir = opendir("./jpg");
char cmd1[255] = "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/";
char cmd_aux[255] = "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/";
char buf[255];
char nomeArq[255];
int i;
//Stretch in which I use openmp
while ((arq = readdir(dir)) != NULL){
strncpy(nomeArq, arq->d_name, 255);
if(nomeArq[0] != '.'){
sprintf(buf, " dcm/imagem-%d.dcm", i);
strcat(cmd1, nomeArq); // cmd1 + nomeArquivo
strcat(cmd1, buf);
system(cmd1);
strncpy(cmd1, cmd_aux, 255);
}
i++;
}
closedir(dir);
return 0;
}
我怎么知道这段代码是 I/O 绑定的,我想问问是否真的不能用 openmp 获得任何加速。如果可能的话,如何在使用 openmp 时并行化这个循环。如果我不是很清楚,对不起!我还在学习英语!
Bash解决方案
首先,如果考虑现有工具,您的任务会更容易:
- GNU Parallel
xargs
带多进程参数
xargs
示例(来自 bash 命令提示符):
ls ./jpg | xargs -P 0 -i ./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/{} dcm/{}.dcm
OpenMP
使用 for
循环更容易,您可以开始将文件列表放入数组中(Whosebug code 了解如何操作)。
// put your code for reading he files list into an array //
int main() {
char **files;
const size_t count = file_list("./jpg", &files);
#pragma omp parallel for
for(size_t i=0;i<count;++i) {
if(files[i][0] == '.' ) { continue; } // 'skip' directory entry, maybe you should implement some better check ( extension, or even checking if it is a file at all)
// keep the buffer local to the loop
char *buf = malloc(1024);
// already calling sprintf, use it for building the whole command line, and avoid the strncpy & strcat
sprintf(buf, "./dcm4che-2.0.23/bin/jpg2dcm -c dcm4che-2.0.23/etc/jpg2dcm/jpg2dcm.cfg jpg/%s dcm/imagem-%zu.dcm",files[i],i);
system(buf);
free(buf); // cleanup
}
return EXIT_SUCCESS;
}