Внедрение языковых расширений языка С#
Используя такие системы, как Parallel Linq, можно разделить выполнение анонимных функций, запросов и т.д. через несколько ядер и потоков в одном машина. Я хотел бы расширить это, чтобы работать на нескольких машинах, используя стандартные языковые конструкции, такие как для циклов (например, Parallel.For()
), типы значений, такие как int
s, struct
s и т.д., И сохранить источник приложения изменения до минимума. В идеале это позволило бы мне открыть проект, добавить атрибут метода и перекомпилировать, чтобы получить доступ к расширенным функциям.
Кажется, что мне нужно что-то вроде:
-
Возможность захватить скомпилированный блок кода (например, лямбда) и передать его рабочему процессу, запущенному на другом node, вместе с любыми требуемыми данными или
-
Предоставьте препроцессор, который будет захватывать данный код, скомпилируйте его в виде проекта шаблона, который заменит ссылки на переменные и т.д. ссылками на класс, который будет обрабатывать сетевую связь, кэширование и доступ к любому другому требуемые активы и отправить полученную DLL всем доступным рабочим узлам, работающим на других машинах.
Roslyn, как представляется, предоставляет некоторые инструменты, которые были бы полезны здесь. Есть ли способ подключиться к текущему конвейеру компиляции, чтобы это разрешить?
Edit
Хорошо, я знаю, это возможно, потому что эти ребята сделали это. Вопрос в том, как?
Ответы
Ответ 1
Вам не нужно распространять языковой труд, чтобы делать то, что делает Брахма. Он только что реализовал пользовательский поставщик запросов, который анализирует деревья выражений и испускает код GPGPU (LINQ to SQL делает то же самое, но с SQL).
Я связал базовое руководство по MSDN здесь, которое поможет вам запустить и запустить поставщика IQueryable
.
Жесткая часть будет перемещаться по деревьям выражений и генерировать код OpenCL. Как только вы сможете это сделать, вы просто передадите его на Cloo, и вы должны бежать.
Edit
Вы связали инструмент, который компилирует стандартный код .NET для кода GPU с атрибутом [Kernel]
. Они делают это, используя инструмент пост-сборки для поиска атрибутов в скомпилированном IL, и они выполняют переписку IL для генерации вызовов GPU. Это похоже на PostSharp, решение AOP.
Переписывание IL требует много времени и тяжелой работы, но вы также можете пройти этот маршрут.
Ответ 2
Используя такие системы, как Parallel Linq, можно разделить выполнение анонимных функций, запросов и т.д. через несколько ядер и потоков в одной машине. Я хотел бы расширить его, чтобы работать на нескольких машинах, используя стандартные языковые конструкции, такие как для циклов (например, Parallel.For()), типы значений, такие как ints, structs и т.д., И чтобы изменения источника приложения были минимальными.
Звучит здорово. На самом деле у нас есть система, очень похожая на систему Microsoft Research, хотя, очевидно, я не могу обсуждать детали.
Мне нужна возможность захватить скомпилированный блок кода (например, лямбда) и передать его рабочему процессу, запущенному на другом node, вместе с любыми требуемыми данными
Хорошо, у тебя это получилось. Мы добавили эту функцию в С# 3. Это то, как работает LINQ to SQL. Как-то запрос LINQ должен попасть в базу данных. Скомпилированный лямбда допрашивается на клиентской машине, преобразуется в запрос, который отправляется на сервер node, а затем возвращается результат.
Roslyn, похоже, предоставляет некоторые инструменты, которые были бы полезны здесь. Есть ли способ подключиться к текущему конвейеру компиляции, чтобы это разрешить?
Это не цель Рослина; Roslyn не говорит о добавлении новых функций на язык С#. Это упрощает анализ кода для создания таких вещей, как механизмы рефакторинга.
Вам не нужно подключаться к конвейеру компиляции. PLINQ не меняет компилятор, LINQ to SQL не меняет компилятор и т.д. Когда вы конвертируете лямбда в дерево выражений, компилятор испускает код, который создает дерево выражений во время выполнения, которое представляет лямбда. Вы можете опросить это дерево выражений, сериализовать его на другой компьютер в своей сети, десериализировать его, превратить в делегата и запустить его, если это то, что вам нравится.
Вам нужно будет написать собственный сериализатор дерева выражений и десериализатор, возможно, но это довольно простые структуры данных. Быть непреложным деревом должно сделать их довольно легко сериализовать и десериализовать; они не могут создавать сложные сети, поскольку они всегда строятся из листовых узлов вверх.