Будет ли Dart выполнять изоляты параллельно в многоядерной среде?

вопрос

будут ли изоляты в Dart работать параллельно, используя все доступные ядра в среде с несколькими ядрами, или он будет мультиплексироваться на одном ядре?

фон

Google описал изолятов (однопоточный блок параллелизма) на языке программирования Dart как "легкий поток", который работает на основном стеке без блокировки.

таким образом, мне кажется, что он сможет только мультиплексировать на одно ядро и не может работать параллельно над несколькими ядрами в среде SMP, dualcore, multicore или clustered.

хотя, я не могу найти никакой информации об этом, поэтому мой скромный вопрос.

3 ответов


предупреждение: приведенный ниже код устарел и не работает с Dart 1.0.

короткий ответ:

может быть.

Ответ

на dart: изолировать руководство библиотеки указано: "изолятов может запуск в отдельном процессе или потоке, в зависимости от реализации. Для веб-приложений, изоляты могут быть скомпилированы для веб-работников, если они доступны." (мой акцент)

при выполнении этого кода и наблюдение за загрузкой процессора скажет вам, делает ли ваша реализация это или нет.

#import('dart:isolate');
main() {
  for (var tmp = 0; tmp < 5; ++tmp) {
    SendPort sendPort = spawnFunction(runInIsolate);
    sendPort.call(tmp).then((reply) {
      print(reply);
    });
  }
}

runInIsolate() {
  port.receive((msg, SendPort reply) {
    var k = 0;
    var max = (5 - msg) * 100000000; 
    for (var i = 0; i < max; ++i) {
        i = ++i - 1;
        k = i;
    }
    reply.send("I received: $msg and calculated $k");
  });
}

автономный dartvm будет run изолирует параллельно, используя все доступные ядра. Браузерные реализации Dart , вероятно, будут разные в зависимости от того, реализованы ли веб-работники или нет.


вот обновленный код для Dart 1.0.

import 'dart:isolate';

main() {
  int counter = 0;

  ReceivePort receivePort = new ReceivePort();

  receivePort.listen((msg) {
    if (msg is SendPort) {
      msg.send(counter++);
    } else {
      print(msg);
    }
  });

  for (var i = 0; i < 5; i++) {
    Isolate.spawn(runInIsolate, receivePort.sendPort);
  }
}

runInIsolate(SendPort sendPort) {
  ReceivePort receivePort = new ReceivePort();
  sendPort.send(receivePort.sendPort);

  receivePort.listen((msg) {
    var k = 0;
    var max = (5 - msg) * 100000000; 
    for (var i = 0; i < max; ++i) {
        i = ++i - 1;
        k = i;
    }
    sendPort.send("I received: $msg and calculated $k");
  });
}

Я посмотрел вверх. Изоляты кажутся реальными нитями.

единственный механизм, доступный для связи между изолятами, - это передача сообщений.

очень хорошо, за исключением

каждый изолят имеет свою собственную кучу, что означает, что все значения в памяти, включая глобалы, доступны только для этого изолята.

совсем не хорошо, из-за сообщений:

также возможно отправить экземпляры объектов (которые будут скопированы в процессе

очень плохо.

эта схема, по-видимому, делает невозможным передачу больших объемов данных из одного изолята в другой без его копирования, поэтому устранение эффективного interisolate общение.

Я бы не использовал его из-за этого ограничения, которое запрещает передачу больших объектов / буферов по адресу, как это обычно делается с обычными нити.

сначала это выглядело интересно, потому что я использую почти исключительно проекты передачи сообщений, но они выбили из строя межпоточные связи, настаивая только на частных кучах.