• [^] # Re: C++ std::future

    Posté par . En réponse à la dépêche Sortie du livre « Parallel and Concurrent Programming in Haskell ». Évalué à 10.

    Pas vraiment.

    Les collections parallèles, et donc les map/reduce/fold parallèles, permettent de travailler sur des collections de manière parallèle de facon totalement transparente.

    L'exemple le plus bateau est de transformer tout les objets d'une liste. Je donne l'exemple en Java par ce que c'est peut être ce qui parlera le plus à quelqu'un qui fait du C++, après entre les différents langage c'est kifkif. En old school tu écrirais:

    List<String> strings = Arrays.asList("a", "aa", "aaa");
    List<Integer> lengths = new ArrayList<>(strings.size());
    for (String str: strings) {
     lengths.add(str.length())
    }

    Avec une API de type stream tu fais ca:

    List<String> strings = Arrays.asList("a", "aa", "aaa");
    List<Integer> lengths = strings.stream()
     .mapToInt(String::length);

    Maintenant disons que ta collection fait quelques millions d'éléments. Tu vois aisément que chaque traitement est indépendant, c'est de l'embarassingly parallel, tu peux facilement laisser le runtime dispatcher ca automatiquement sur plusieurs cores:

    List<String> strings = Arrays.asList("a", "aa", "aaa");
    List<Integer> lengths = strings.parallelStream()
     .mapToInt(String::length);

    Le seul changement c'est stream contre parallelStream. La première version est séquentiel, la seconde parallèle. C'est totalement transparent pour toi. Évidement tu peux faire des choses un peu plus compliquée avec d'autres opérateurs du même type. Pour te donner une petite idée tu peux regarder les nouveautée de Java8 ca doit être accessible et parlant à n'importe qui qui fait de l'objet (en regardant uniquement ce qui touche les collections/streams). Ou aussi n'importe quel doc sur les collections de Scala.

    En fonctionnel, ce type de traitement est la base. Tu passes ton temps à exécuter des fonctions qui transforment des données immutables en d'autres.

    Si on va plus loin, on pourrait aussi faire ces opérations de manière distribuée c'est à dire en utilisant plusieurs machines. Comme pour le parallèle, plusieurs cores, cela à un coût (transfert réseau etc.) mais il peut être amorti selon le cas d'utilisation. Très très basiquement, c'est ce permet fait Hadoop. En vrai un système distribué à des contraintes qu'un système parallèle n'a pas donc c'est un peu différent.

    std::async et std::future te permettent eux de faire du parallélisme explicite. Tu définis un traitement a effectuer de manière asynchrone et tu récupères un future qui te permet de récupérer le résultat du traitement lorsqu'il est fini (sans bloquer si tu le souhaites). Basiquement c'est du sucre syntaxique au dessus des threads, possiblement d'un threadpool, et d'un objet permettant de communiqué une valeur entre l'appelant et le thread. Ce sont donc deux approches différentes et complémentaire du parallélisme. Tu ne les utilises pas au même endroit ni pour faire la même chose. Il en existe d'autres.