Будет ли Дарт выполнять изоляцию параллельно в многоядерной среде?
Вопрос
Будет ли изолировать в 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
Я посмотрел. Изоляты, по-видимому, являются актуальными потоками.
Единственным механизмом, доступным для связи между изолятами, является передача сообщений.
Очень хорошо, кроме
Каждый изолятор имеет свою собственную кучу, а это означает, что все значения в памяти, включая глобальные, доступны только для этого изолята.
Совсем не хорошо, из-за сообщений:
также можно отправлять экземпляры объектов (которые будут скопированы в процессе
Очень плохо.
Эта схема, по-видимому, делает невозможным передачу больших объемов данных из одного изолированного в другое без их копирования, что устраняет эффективную межсоединенную связь.
Я бы не использовал его из-за этого ограничения, которое запрещает передачу больших объектов/буферов по адресам, как это обычно делается с обычными потоками.
Сначала это выглядело интересно, потому что я использую почти исключительно проекты для передачи сообщений, но они изматывали межпоточные комм, настаивая только на частных кучах.