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

Вопрос

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

Фон

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

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

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

Ответ 1

Предупреждение: приведенный ниже код устарел и не работает с 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 будет запускать изоляты параллельно, используя все доступные ядра. Реализации браузера Dart, вероятно, будут меняться в зависимости от того, реализованы ли веб-рабочие или нет.

Ответ 2

Вот обновленный код для 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");
  });
}

Ответ 3

Я посмотрел. Изоляты, по-видимому, являются актуальными потоками.

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

Очень хорошо, кроме

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

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

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

Очень плохо.

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

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

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