Реализация языковых расширений C # - PullRequest
16 голосов
/ 28 декабря 2011

Используя такие системы, как Parallel Linq , можно разделить выполнение анонимных функций, запросов и т. Д. По нескольким ядрам и потокам на одном компьютере. Мне бы хотелось иметь возможность расширять его для работы на нескольких машинах, используя стандартные языковые конструкции, такие как циклы for (например, Parallel.For()), типы значений, такие как int s, struct s и т. Д., И сохранять исходный код приложения. модификации до минимума. В идеале это позволило бы мне открыть проект, добавить атрибут к методу и перекомпилировать, чтобы получить доступ к расширенной функциональности.

Кажется, мне нужно что-то вроде:

  1. Возможность захвата скомпилированного блока кода (такого как лямбда-выражение) и передачи его рабочему процессу, выполняющемуся на другом узле, вместе со всеми необходимыми данными или

  2. Предоставить препроцессор, который будет захватывать рассматриваемый код, скомпилировать его в своего рода шаблонный проект, который заменит ссылки на переменные и т. Д., Ссылками на класс, который будет обрабатывать сетевое взаимодействие, кэширование и доступ к любому другому необходимые ресурсы и отправьте полученную DLL на все доступные рабочие узлы, работающие на других машинах.

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

Редактировать

Хорошо, я знаю это возможно, , потому что эти ребята сделали это . Вопрос в том, как ?

Ответы [ 2 ]

11 голосов
/ 28 декабря 2011

Используя такие системы, как Parallel Linq, можно разделить выполнение анонимных функций, запросов и т. Д. Между несколькими ядрами и потоками на одном компьютере.Мне бы хотелось иметь возможность расширять его для работы на нескольких машинах, используя стандартные языковые конструкции, такие как циклы for (например, Parallel.For ()), типы значений, такие как int, структуры и т. Д., И сводить к минимуму модификации исходного кода приложения..

Звучит отлично.На самом деле, у нас очень похожая система в Microsoft Research, хотя, очевидно, я не могу обсуждать детали.

Мне нужна возможность захвата скомпилированного блока кода (такого как лямбда) ипередать его рабочему процессу, работающему на другом узле, вместе с любыми необходимыми данными

ОК, вы получили его.Мы добавили эту функцию в C # 3. Вот как работает LINQ to SQL. Каким-то образом запрос LINQ должен попасть в базу данных.Скомпилированная лямбда-запрос запрашивается на клиентском компьютере, преобразуется в запрос, который отправляется на узел сервера, и затем результат отправляется обратно.

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

Это не цель Рослина;Roslyn не о добавлении новых функций в язык C #.Речь идет об упрощении анализа кода для создания таких вещей, как механизмы рефакторинга.

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

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

10 голосов
/ 28 декабря 2011

Вам не нужно расширять язык, чтобы делать то, что делает Брахма.Он только что реализовал пользовательский поставщик запросов, который анализирует деревья выражений и генерирует код GPGPU (LINQ to SQL делает то же самое, но с SQL).

Я привел базовое руководство по MSDN здесь , которое можетприступим к реализации поставщика IQueryable.

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

Редактировать

Вы связали инструмент, который компилирует стандартный код .NET с кодом GPU.с атрибутом [Kernel].Они делают это с помощью инструмента пост-сборки, который ищет атрибуты в скомпилированном IL, и выполняют перезапись IL для генерации вызовов GPU.Это похоже на PostSharp , решение АОП.

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

...