como contábamos en una entrada anterior, últimamente hemos estado liados trabajando con archivos FASTQ de varios GBs, con decenas de millones de lecturas o reads. Para algunas de las tareas que hemos tenido que realizar, como ordenar o renombrar, nos hemos dado cuenta que lenguajes interpretados como Perl o Python son varias veces más lentos que caballos de carreras compilados como C/C++, como también comenta el autor de readfq, por ejemplo.
Por eso he estado refrescando la Standard Template Library (STL) de C++, que para alguien acostumbrado a programar en lenguajes de alto nivel es esencial, como recurso para crear estructuras de datos flexibles y eficientes en programas escritos en C/C++. Como dice Scott Meyers en su libro Effective STL, probablemente los contenedores más populares de la STL son
std::count
std::find
std::search
std::replace
std::max_element
std::merge
std::min_element
std::nth_element
std::set_union
std::set_intersection
std::sort
Esquema de sort parelelo y merge posterior, tomado de http://javaero.org/tag/parallel-merge-sort |
El siguiente ejemplo de sort en paralelo, que depende de la librería OpenMP, se compila con $ g++ -O3 -fopenmp -o testP testP.cc para generar un ejecutable que empleará 4 cores para ordenar un millón de palabras de 25 caracteres de longitud:
#include <stdlib.h>
#include <omp.h>
#include <vector>
#include <parallel/algorithm>
using namespace std;
// g++ -O3 -fopenmp -o testP testP.cc
// http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html
#define MAXTHREADS 4;
string randomStrGen(int length)
{
//http://stackoverflow.com/questions/2146792/how-do-you-generate-random-strings-in-c
static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890;:|.@";
string result;
result.resize(length);
for (int i = 0; i < length; i++) result[i] = charset[rand() % charset.length()];
return result;
}
int main()
{
unsigned threads = MAXTHREADS;
omp_set_dynamic(false);
omp_set_num_threads(threads);
srand(time(NULL));
std::vector<string> data(1000000);
for(int i=0;i<data.size();i++) data[i] = randomStrGen(25);
__gnu_parallel::sort(data.begin(), data.end()); //std::less<string>() , std::smaller<string>() );
printf("%s\n%s\n%s\n%s\n",data[0].c_str(),data[1].c_str(),data[2].c_str(),data[data.size()-1].c_str());
return 0;
}
Referencias más avanzadas:
[1] http://algo2.iti.kit.edu/singler/mcstl/parallelmode_se.pdf
[2] http://ls11-www.cs.uni-dortmund.de/people/gutweng/AD08/VO11_parallel_mode_overview.pdf
Hasta luego,
Bruno