8
votes

Java multithreading dans un ordinateur portable ayant un processeur quad-core

Je traversais un tutoriel Java où il a été mentionné que la multithreading réelle ne se produit pas dans une machine ayant un seul processeur. Il a mentionné que OS attribue une quantité de temps spécifiée pour le processus Java et le planificateur de thread JVM ramasse des threads pour exécuter un fil à la fois pendant une petite quantité de temps.

J'ai un ordinateur portable quel processeur quadcore - il est possible d'exécuter un programme multi-threadé plus rapidement de manière programmée en exécutant un fil dans chaque noyau? La raison pour laquelle je pose cette question est parce que le livre a indiqué que seul un véritable système multi-processeurs peut faire plusieurs choses en même temps.


2 commentaires

Je suis allé de l'avant et a ajouté la balise multithreading à cette question - ce n'est pas seulement une question de Java-Centric. Espérons que vous obtiendrez de bonnes réponses.


L'article que vous avez lu était probablement de temps avant les processeurs multicœurs, alors stipule que seul l'ordinateur multiprocesseur peut l'utiliser.


4 Réponses :


2
votes

Même avec un seul processeur Plusieurs threads peuvent rendre votre programme plus rapidement, tout dépend du travail que vous essayez d'accélérer. Par exemple, si vos discussions attendent IO. Si c'est purement calculal, vous voudrez probablement limiter vos fils à votre nombre de cœurs.

Mesurez-le, testez-le avec des expériences.


0 commentaires

2
votes

Un processeur multicœur peut "véritablement" paralléliser le travail dans votre application jusqu'au nombre de cœurs que vous avez. Dans votre cas, ce serait 4 threads. En savoir plus sur Multi-Core vs multi-processeur à Wikipedia . Cela dit, vous pouvez réaliser des avantages de performance avec un algorithme multi-fileté sur un processeur de base unique, malgré le fait que vous n'avez qu'un seul processeur.

L'amélioration des performances gagnées par l'utilisation d'un multicœur le processeur dépend beaucoup des algorithmes logiciels utilisés et de leur la mise en oeuvre. En particulier, les gains éventuels sont limités par le fraction du logiciel pouvant être parléglémentaire à exécuter sur plusieurs cœurs simultanément; Cet effet est décrit par la loi d'AMDAHL. Dans le meilleur cas, soi-disant problèmes parallèles embarrassants peut réaliser facteurs de vitesse près du nombre de cœurs, voire plus si le problème est suffisamment divisé pour s'adapter dans les cache (s) de chaque noyau, évitant l'utilisation de beaucoup plus lent de la mémoire du système principal. La plupart des applications, cependant, ne sont pas accéléré tellement à moins que les programmeurs investissent une quantité prohibitive de Effort dans la ré-adapte tout le problème 2 . La parallélisation de Le logiciel est un sujet de recherche important important.

Voir aussi ce Stackoverflow question.


0 commentaires

1
votes

Je peux confirmer que, sur mon ordinateur portable I3, des algorithmes qui fonctionnent en parallèle vont près de deux fois plus d'aspects rapides un algorithme de série.

Plus de contexte ajouté ci-dessous ...

Ce sont des algorithmes très computinents sans I / O. Fondamentalement, calculez les statistiques sur N de grandes matrices, où chaque matrice peut être effectuée de manière indépendante. Je trouve que, à l'aide d'un bassin de fil de 2-4 threads, tous les rendements de la même vitesse augmentent - 2x. Aller à 8 fils ou plus, les choses commencent légèrement lorsque vous obtenez plus de contentions (et utilisez plus de mémoire). Sur un processeur avec plus de noyaux, ces valeurs changeraient.


0 commentaires

8
votes

Même un seul processeur peut faire "plusieurs choses en même temps" dans un sens lâche, mais ils ne sont pas vraiment en parallèle. Vous pouvez démarrer 100 threads à exécuter sur un seul noyau et obtenir des tranches de temps au cours de laquelle chacun d'eux peut exécuter quelques instructions, créant ainsi l'impression qu'ils exécutaient tous en même temps.

Comme je l'ai dit Dans un autre après-poste: multithreading sur la machine double noyau? P >

Le terme threads couvre généralement trois couches d'abstraction: p>

  1. Les threads utilisateur forts> sont des threads lancés par des applications et sont mappés N: M à: li>
  2. Fils de noyau strong>, qui sont des threads gérés par le système d'exploitation, mappé N: M à: LI>
  3. THERNIÈRES HARDWARE STROND>, qui sont les ressources physiques réelles disponibles. Li> ol>

    Les threads Java sont des threads utilisateur. Les 4 cœurs de votre CPU comptent comme threads matériels. Étant donné que la cartographie est N: m à travers les couches, vous pouvez voir que plusieurs threads d'utilisateur sont mappés sur un nombre plus petit de filets matériels. P>

    Maintenant, après cela, il y a généralement deux classes d'activités de fil, chacune avec leurs propres bizarreries: p>

    1. fils d'E / S strong>: ces threads passent la majeure partie de leur temps à attendre des opérations de lecture / écriture à partir d'un flux et sont bloquées entre-temps (ils ne sont pas programmés pour l'exécution jusqu'à ce qu'un événement ne se reproduise les haut). Il y a une lumière sur la CPU et beaucoup d'entre eux peuvent courir simultanément même sur un seul noyau. Li>
    2. threads de calcul strong>: ces threads font beaucoup de chiffres et utilisent la CPU au maximum. Commencez généralement plus de (2x le nombre de cœurs disponibles) Ces threads vont dégrader les performances, car la CPU dispose d'un nombre limité d'unités fonctionnelles: Alus, FPUS, etc. Li> ol>

      La deuxième classe de threads ci-dessus vous permet de voir vraiment l'avantage ou d'exécuter un programme Java multithreaded sur votre processeur quad-core. Voici un exemple simple d'un programme exécutant de 1.000.000.000 numéros d'abord séquentiellement, puis en parallèle à l'aide d'une piscine de thread avec 4 threads: P>

      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.TimeUnit;
      
      class ThreadTask implements Runnable {
      
          private int total = 0;
      
          public ThreadTask(int total) {
              this.total = total;
          }
      
          @Override
          public void run() {
              int value = 0;
              for(int i = 0; i < total; i++) {
                  value = i * i;
              }
          }       
      }
      
      public class Test {
      
          public static void main(String[] args) throws InterruptedException {
      
              int total = 1000000000;
      
              long start = System.currentTimeMillis();
              long value = 0;
              for(int i = 0; i < total; i++) {
                  value = i * i;
              }       
              long stop = System.currentTimeMillis();
      
              System.out.println((stop - start) + " ms");
      
              ExecutorService exec = Executors.newFixedThreadPool(4);
              start = System.currentTimeMillis();
              for(int i = 0; i < 4; i++) {
                  exec.submit(new ThreadTask(total / 4));
              }
              exec.shutdown();
              exec.awaitTermination(10, TimeUnit.SECONDS);
              stop = System.currentTimeMillis();
      
              System.out.println((stop - start) + " ms");     
          }
      }
      


1 commentaires

Merci Tudor - va essayer cela :)