Как скомпилировать C# для многопроцессорных машин? (с VS 2010 или csc.exe)

Привет!

Я искал параметры компилятора (csc.exe) в MSDN. и я нашел ответ здесь, в Stackoverflow, о компиляция с несколькими процессорами. Но моя проблема заключается в компиляции для нескольких процессоров следующим образом.

В университете, который я заканчиваю, есть кластер из 11 машин (в котором 6 четырехъядерных и 5 четырехъядерных двухпроцессорных машин). Он работает под linux, но я могу установить туда MONO. И вместо того, чтобы компилировать с несколькими процессорами или ядрами, я хочу скомпилировать для многопроцессорной машины. Так:

  • Есть ли какая-либо конкретная информация о том, как это сделать, или CLR в этой системе должна обрабатывать выполнение, чтобы распределить его по ядрам?
  • Если есть способ сделать это, как мне это сделать с помощью VS2010 или компилятора командной строки csc.exe?

Заранее благодарим и извините, если этот вопрос не имеет смысла. Я действительно не знаю, как обращаться с несколькими ядрами, так как я всего лишь физик, а не программист! :)


person Girardi    schedule 07.03.2011    source источник
comment
Кстати, если вы планируете использовать что-то еще, кроме .NET, вы найдете гораздо больше возможностей для распределенных вычислений.   -  person SK-logic    schedule 07.03.2011
comment
Интересно, что... Но до сих пор C# был самым простым в использовании (компилируемым) языком, который я знал (с моей точки зрения). Я сравниваю его с C, C++, FORTRAN (77, 90, 95), Java, Pascal и Object Pascal. Его простота поражает. Я действительно хочу потратить некоторое время на C ++, но моя работа со временем, чтобы закончить магистратуру, не позволяет мне сделать это...   -  person Girardi    schedule 07.03.2011
comment
Поскольку вы занимаетесь какой-то физикой, вас может больше интересовать доступность соответствующих библиотек, чем сам язык программирования. Для Фортрана существует множество числовых библиотек, а для .NET не так много. И есть специальные языки для вычислений, такие как Matlab (или Octave), R и Mathematica. В зависимости от сложности ваших задач вы можете в конечном итоге реализовать слишком много уже существующей функциональности, если выберете неспециализированный язык.   -  person SK-logic    schedule 07.03.2011
comment
Да, я знаю об этом... Я также нашел несколько интересных библиотек для C#... Извините, но я отказываюсь использовать FORTRAN, во-первых, потому что это не объектно-ориентированный подход, а во-вторых, потому что он не поддерживает XML входные файлы... Я бы не хотел писать длинные текстовые файлы, чтобы читать их в программе, когда я могу писать файлы метаданных для этого... MATLAB тоже хороший язык, он очень быстрый, но его больше всего для матричных вычислений ... Абстракция объектно-ориентированного программирования - это то, что удерживает меня на C # или некоторых ненаучных языках (несмотря на производительность по сравнению со структурированным языком).   -  person Girardi    schedule 07.03.2011


Ответы (5)


Поскольку это кластер, вы должны полагаться на некоторую форму параллелизма передачи сообщений, никакой компилятор не будет автоматически преобразовывать ваш код. По крайней мере, поддерживается старый добрый MPI: http://osl.iu.edu/research/mpi.net/

person SK-logic    schedule 07.03.2011
comment
Эй, я прочитал описание MPI, и кажется, что с ним очень здорово работать... Но для того, чтобы использовать его, я должен установить новую среду выполнения, не так ли? Кроме того, библиотека параллельных задач, упомянутая в других вопросах, не справится с проблемой нескольких ядер? - В любом случае, спасибо за вашу помощь, и я добавил сайт MPI в избранное! - person Girardi; 07.03.2011
comment
@Girardi, есть 100% CLI-реализация MPI и простая оболочка. Для оболочки вам понадобится только установленный скомпилированный собственный MPI (скорее всего, он у вас уже есть), для управляемой реализации вам ничего не нужно. Библиотека TaskParallel будет обрабатывать несколько ядер, но не поможет с несколькими узлами, тогда как при передаче сообщений вы можете использовать все доступные ядра. Еще одна библиотека, используемая в физике, — PVM3, но я никогда не видел для нее оберток .NET, я использовал ее только с Fortran. - person SK-logic; 07.03.2011
comment
Короче говоря, в чем разница между многоядерным и многоузловым? - person Girardi; 07.03.2011
comment
@Girardi: первое относится к нескольким процессорам на одном компьютере, где используется общая память. Последнее относится к нескольким машинам, где используется сетевая инфраструктура (часто называемая сеткой). - person Adam Robinson; 07.03.2011
comment
@Girardi, для многоядерных (или многопроцессорных) у вас есть общая быстрая память с произвольным доступом. Это позволяет использовать определенный стиль программирования, реализованный в библиотеке TaskParallel и других подходах, основанных на потоках. Но ваш кластер состоит из нескольких узлов, которые могут совместно использовать быструю сеть, но не один пул общей памяти. В этом случае единственным доступным методом программирования является передача сообщений. Передача сообщений происходит очень быстро, когда процессы занимают ядра ЦП одного узла, и достаточно быстро, когда они находятся на разных узлах. - person SK-logic; 07.03.2011

Вам не нужно компилировать по-другому, чтобы учесть несколько ядер. Однако вам нужно написать свой код по-другому, чтобы использовать несколько потоков. Если вы можете использовать классы из .NET 4 в своей среде (последняя версия Mono должна это поддерживать), вы можете использовать библиотеку параллельных задач, которая немного упрощает эту задачу.

По сути, вы не получаете параллелизм бесплатно — вам нужно думать о том, какие фрагменты вашего кода могут разумно выполняться параллельно. Возможно, вы захотите ознакомиться с выводами группы Шаблоны и рекомендации для параллельного программирования. (Книга является очень хорошей отправной точкой.)

person Jon Skeet    schedule 07.03.2011
comment
Эй, спасибо за ответ ... Читая ответ и комментарии SK-Logic, я пришел к этому сомнению в том, что мне действительно следует использовать ... Как он сказал, TPL обрабатывает только многоядерные, а не многоузловые приложения. .. - person Girardi; 07.03.2011

Ваше предположение верно; ваш вопрос не имеет смысла.

Невозможно волшебным образом распараллелить произвольный код; вам нужно изменить код, чтобы использовать несколько потоков.

Вы можете явно использовать несколько ядер в C# с помощью классов Thread или ThreadPool либо с помощью Parallel LINQ или TPL.
Никакого специального компилятора не требуется.

person SLaks    schedule 07.03.2011
comment
На самом деле вопрос имеет смысл. Теоретически можно автоматически преобразовать простой последовательный код в параллельный, а затем вывести для него специализированный протокол передачи сообщений. Конечно, .NET слишком сложен для такого вывода, но для какого-то чисто функционального языка это вполне возможно. - person SK-logic; 07.03.2011

CLR по умолчанию не делает ничего особенного для распределения работы между несколькими ядрами. ВЫ, разрабатывая приложение, несете ответственность за максимально эффективное использование ресурсов вашего компьютера. В .NET Framework есть несколько библиотек и технологий, упрощающих реализацию многопоточных операций: найдите класс Thread, Delegate.BeginInvoke/EndInvoke и библиотеку Task Parallel.

person KeithS    schedule 07.03.2011

Ответ на ваш вопрос приходит в виде двух, казалось бы, противоречащих друг другу утверждений:

1: Это уже так

а также

2: Вы не можете

Современные операционные системы и, следовательно, среды разработки используют потоки. Поток, по сути, представляет собой одну серию последовательных шагов (и слов, которые не начинаются с буквы "S"), которые будет выполнять процессор. Эти потоки управляются операционной системой и архитектурой процессора, при этом процессор выполняет некоторую часть (или весь) потока, сохраняет свое состояние, а затем переключается на другой поток.

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

Рискуя использовать слишком упрощенное сравнение, подумайте об этом так: ваш код в его нынешнем виде представляет собой просто очень длинный список шагов, которые необходимо выполнить для выполнения конкретной задачи. Теперь вы взяли этот список инструкций в комнату, полную людей (каждый из которых представляет процессорное ядро), и вы хотели бы использовать каждого из этих людей как можно эффективнее. В то время как комната, полная аспирантов, может иметь контекст и знания по предмету, чтобы понять, как разбить ваши инструкции на задачи для каждого отдельного человека, вы принесли свой список в комнату, полную людей, которые отлично следуют указаниям. но совершенно глупо, когда дело доходит до дедукции. В этом случае вам нужно предоставить разные наборы инструкций для каждого человека, чтобы при выполнении всех вы получили один и тот же результат.

Проще говоря, чтобы ваш код мог использовать преимущества нескольких ядер или процессоров, вы должны разбить свою работу на небольшие, предпочтительно атомарные фрагменты кода. Конкретный метод, который вы используете для разбиения кода на несколько потоков, может различаться; использование System.Threading.ThreadPool или недавно представленной библиотеки параллельных задач может упростить некоторые из этих вещей, хотя всегда есть компромисс (как и во всем) либо в эффективности, либо в контроле.

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

person Adam Robinson    schedule 07.03.2011
comment
Обратите внимание, что многопоточность здесь не поможет, так как OP спрашивает о распределенных вычислениях. - person SK-logic; 07.03.2011
comment
@SK-logic: хотя они, очевидно, разные звери в приложении, проблемы дизайна в основном одинаковы: разбивка вашего кода на части, которые можно распределить между несколькими вычислительными ядрами (будь то на одной машине или в части сетки) . - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, эти два подхода (передача сообщений и общая память) абсолютно и несовместимы. И, конечно, все эти разговоры о библиотеке TaskParallel и ThreadPool абсолютно неуместны и совершенно не помогут, они не подходят для этой задачи. И две модели спроектированы по-разному, за ними стоит разная математика. - person SK-logic; 07.03.2011
comment
@SK: Те, кто говорит в абсолютах, как правило, имеют проблемы с кровяным давлением. Как я уже сказал, они разные звери в применении. Общность - и то, что OP отсутствует, что делает его (ИМХО) наиболее важной частью - заключается в том, что инструкции должны быть разбиты вручную, а не переключатель компилятора. - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, даже это неправда. Это можно сделать автоматически, в зависимости от вашего исходного языка. Например, это проще простого с чистыми функциональными языками. Можно настроить компилятор для использования либо потоков, либо IPC для языков, основанных на исчислении Пи (например, Оккама). Теоретически возможно автоматически распараллелить даже императивный код, поэтому можно спросить, может ли компилятор уже сделать это. К сожалению, такие компиляторы пока чисто академические и пока не будут работать с C-подобными языками. - person SK-logic; 07.03.2011
comment
@SK: Пока у вас нет решения проблемы с остановкой, невозможно распараллелить произвольный код. Да, функциональные языки спроектированы таким образом, что функции являются гражданами первого класса, а большинство типов данных являются неизменяемыми (что решает проблему параллелизма), но это не просто переключатель, который можно щелкнуть. - person Adam Robinson; 07.03.2011
comment
Спасибо за самое объяснение! - person Girardi; 07.03.2011
comment
@ Адам Робинсон, это интригует. Какова связь между проблемой остановки и автоматическим распараллеливанием? И, просто для справки, вы можете перевести любой императивный код в чистый функциональный, используя простое SSA-преобразование. Таким образом, все, что возможно для функционального кода, возможно и для любого императивного кода. Я использую эту технику для определения блоков кода, которые можно транслировать в ядро ​​OpenCL или CUDA, но то же самое можно сделать и для более сложного параллелизма. - person SK-logic; 07.03.2011
comment
@SK: Связь заключается в контексте двух вопросов: чтобы распараллелить произвольный код, компилятору придется пройти те же шаги, что и любому человеку: проверить код, найти побочные эффекты и принять решение о модель на основе параллелизма или без сохранения состояния (последняя из которых является единственным практичным вариантом в сценариях распределенных вычислений). Чтобы сделать это, наивный подход (и, насколько мне известно, единственный допустимый подход для произвольного кода, поскольку мы не можем делать никаких контекстуальных предположений) представляет собой рекурсивный анализ всего кода до тех пор, пока он достигает некоторого уровня общего кода (будь то - person Adam Robinson; 07.03.2011
comment
(продолжение) SDK ОС, общий набор библиотек или набор инструкций ядра микропроцессора вместе с картой зарезервированных ячеек памяти ввода-вывода и кодов прерываний), пока не будет получена полная картина о конкретном фрагменте кода. Да, в некоторых (возможно, во многих) случаях при наличии достаточного времени и вычислительной мощности компилятор может успешно определить схему распараллеливания для данного фрагмента кода. Но говорить о простом империативно-›функционально-параллельном сдвиге — даже с учетом теоретических подходов компилятора — поспешно. Может быть, когда-нибудь, но не сейчас. - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, абстрактной интерпретации более чем достаточно, чтобы решить, независимы ли два потока. И вам не нужно следовать всем возможным путям потока в абстрактном интерпретаторе. К счастью, мы не говорим о простом ужасном C с арифметикой указателей, это хороший управляемый C#, поэтому невозможны неожиданные перекрытия доступа к памяти. А пока нет - у меня есть рабочий прототип. - person SK-logic; 07.03.2011
comment
@СК: Конечно. Кто сказал, что мой код C# не взаимодействует с другими (потенциально неуправляемыми) библиотеками? Кто сказал, что я не использую код unsafe и не занимаюсь, как вы упомянули, арифметикой указателей? Кто сказал, что я не взаимодействую с другой системой по сетевому протоколу? Я не говорю, что вы не можете квалифицировать код, отвечающий вашим требованиям, и затем автоматически распараллелить его. Я сказал, что вы не можете взять произвольный код (который включает в себя все эти неудобно полезные вещи, такие как взаимодействие с другими неуправляемыми библиотеками и выполнение ввода-вывода) и распараллелить его. - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, обнаружить и изолировать небезопасные вещи довольно просто. Если указатель попадает в неуправляемый мир, вся иерархия испорчена. Если есть неизвестный, неаннотированный неуправляемый вызов, ветвь потока испорчена. И помните, на практике вы, скорее всего, захотите распараллелить числовой код. Обычно это очень просто и не делает ничего из ужасных вещей, которые вы упомянули - ничего, кроме простого доступа к массиву. Нет смысла распараллеливать произвольный код, чего стоят только точки производительности. - person SK-logic; 07.03.2011
comment
@SK: Теперь вы изменили свой аргумент. Моя исходная точка зрения заключалась в том, что вы не можете автоматически распараллелить произвольный код. Вы сказали: теоретически возможно автоматически распараллелить даже императивный код. Я сказал, что пока у вас не будет решения проблемы с остановкой, распараллелить произвольный код невозможно. Затем вы усомнились в связи между проблемой остановки и распараллеливанием произвольного кода (которое я позже объяснил), а теперь вы меняете правила, называя код испорченным. Я не уверен, работаете ли вы в академической или коммерческой сфере. - person Adam Robinson; 07.03.2011
comment
(продолжение) мир (и я действительно не имею в виду это в пренебрежительном смысле), но кажется довольно натянутым называть использование внешней библиотеки или операции ввода-вывода ужасными. Небезопасный код, да, он должен быть помечен unsafe по какой-то причине, но другие вполне допустимы и общие вещи в бизнес-приложениях. Такие вещи должны быть настроены кем-то, кто знает, что происходит. Моя точка зрения в этом обсуждении (что произвольный код не может быть автоматически распараллелен, по крайней мере пока) не изменилась; у твоего, кажется, есть. - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, да, вы не можете автоматически распараллеливать произвольный код с неизвестными частями (внешними библиотеками и т. д.). Живой программист тоже не сможет этого сделать. Но вы можете автоматически распараллелить произвольный императивный код, если у вас есть доступ ко всему этому. И даже наличие арифметики указателей не будет проблемой. Ввод/вывод вообще не проблема. И никто не собирается распараллеливать произвольное бизнес-приложение, все дело в научных вычислениях. Что касается испорченной памяти - при случайном непредсказуемом доступе к ней ни один живой программист тоже не сможет ее распараллелить. - person SK-logic; 07.03.2011
comment
Итак, эта заразная вещь предназначена для изоляции кода с неизвестным поведением. Нет никакой разницы между компилятором и живым программистом, так как поведение кода черного ящика неизвестно обоим. - person SK-logic; 07.03.2011
comment
@SK: Но дело в том, что компьютер не имеет такой же точки зрения, как программист; программист может (и, надеюсь, знает) знать поведение внешней библиотеки и объяснить его. И нет, распараллеливание совершенно определенно не ограничивается научными вычислениями. Это огромная проблема и в коммерческом развитии. Дело здесь в том, что возможно — и весьма вероятно — что программист знает что-то, чего компьютер не знает и не может открыть для себя. - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, ОП явно спрашивает о контексте научных вычислений. Сколько внешних библиотек вы видели, которые позволяют передавать указатели на большие, глубокие структуры? Все взаимодействие всегда ограничивается не чем иным, как массивами. В реальном мире это не проблема. - person SK-logic; 07.03.2011
comment
@SK: Опять же, я сказал произвольный код, и вы попросили меня уточнить. Я не понимаю, почему вы продолжаете разговор о распараллеливании произвольного кода, когда соглашаетесь с тем, что это невозможно. Если вы чувствовали тогда, что то, о чем я говорил, было либо неуместным, либо бессмысленным, почему бы не сказать мне об этом вместо того, чтобы вступать в дискуссию об этом? Я согласен, ОП явно говорит о научном контексте, и то, что вы делаете, вероятно, соответствует тому, что ему нужно (вы знаете гораздо больше о грид-вычислениях, чем я; здесь нет аргументов), - person Adam Robinson; 07.03.2011
comment
(продолжение) но люди, которые позже рассматривают этот вопрос — и ответы — не обязательно будут исходить из этой точки зрения. Когда они видят, что кто-то утверждает, что может автоматически распараллеливать код (а затем утверждает, что да, это работает для любого произвольного кода), они либо должны знать о ваших предположениях о коде, либо должны быть осведомлены о том, что это невозможно во всех случаях ( возможно, большинство, если смотреть в более крупном масштабе). - person Adam Robinson; 07.03.2011
comment
@ Адам Робинсон, я считаю, что по-прежнему возможно автоматически распараллелить произвольный код, даже если о большей его части ничего не известно. Я не говорю о наилучшем возможном распараллеливании, конечно. И, поскольку современный код гораздо менее похож на спагетти, чем раньше, все ваши опасения уже не так страшны. Вы ничего не знаете о части кода, и вам все равно - вы все равно можете распараллелить код, который зависит от данных, недоступных для неизвестной части. Вот и все. Таким образом, в большинстве реальных случаев вполне возможно выполнить автоматическое распараллеливание. - person SK-logic; 07.03.2011