C # принципиально не переносимый? - PullRequest
16 голосов
/ 29 сентября 2010

Я уже некоторое время использую C # и недавно начал работать над добавлением параллелизма в мой сторонний проект.Так, согласно Microsoft, читает и записывает в целые числа и даже числа с плавающей запятой атомарные

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

Проблема только усугубляется тем фактом, что int всегда всегда-bits.Есть много встроенных устройств, которые не могут атомарно выполнить 32-битную запись.

Кажется, это фундаментальная ошибка в C #.Гарантировать атомарность этих типов данных нельзя с помощью переносимости.

Как эти гарантии атомарности предназначены для реализации на архитектурах, где нет FPU или 32-битных записей?

Ответы [ 5 ]

12 голосов
/ 29 сентября 2010

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

Итог: C # (основной язык, не считая некоторых платформо-зависимых API) так же переносим, ​​как и Java.

7 голосов
/ 29 сентября 2010

Будущее произошло вчера, C # фактически портирован на большое количество встроенных ядер. .NET Micro Framework - это типичный сценарий развертывания. Номера моделей, которые я вижу в качестве собственных целей: AT91, BF537, CortexM3, LPC22XX, LPC24XX, MC9328, PXA271 и SH2.

Я не знаю точных деталей реализации их набора инструкций ядра, но я вполне уверен, что это все 32-битные ядра, и некоторые из них являются ядрами ARM. Написание многопоточного кода для них требует минимальной гарантии, и атомарные обновления для правильно выровненных слов являются одним из них. Учитывая поддерживаемый список и то, что 4-байтовые атомарные обновления для выровненных слов тривиально реализовать на 32-битном оборудовании, я надеюсь, что все они действительно поддерживают его.

7 голосов
/ 29 сентября 2010

Для этого предназначен CLI.Я сомневаюсь, что они сертифицируют реализацию, если она не соответствует требованиям.Таким образом, в основном C # переносим на любую платформу, которая его имеет.

6 голосов
/ 30 сентября 2010

В отношении «переносимости» есть две проблемы:

  1. Может ли быть реализована практическая реализация языка для различных платформ
  2. Будет ли программа, написанная на языке, корректно работать на разных платформах без изменений

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

Например, большая часть сетевого кода опирается на тот факт, что (на большинстве платформ) символ без знака равен восьми битам, а 32-разрядное целое число представлено четырьмя символами без знака в порядке возрастания или убывания. Я использовал платформу, где char был 16 бит, sizeof (int) == 1 и sizeof (long) == 2. Автор компилятора мог бы сделать так, чтобы компилятор просто использовал нижние 8 бит каждого адреса, или мог бы добавить много дополнительного кода, чтобы написание указателя 'char' сдвигало адрес на один бит вправо (сохраняя lsb), читая адрес, обновите верхнюю или нижнюю половину на основе сохраненного адреса lsb и запишите его обратно. Любой из этих подходов позволил бы запускать сетевой код без изменений, но сильно затруднил бы полезность компилятора для других целей.

Некоторые из гарантий в CLR означают, что нецелесообразно внедрять его на любой платформе с атомарным размером операций меньше 32 бит. И что? Если микроконтроллеру требуется более нескольких десятков Кбайт пространства кода и оперативной памяти, разница в стоимости между 8-разрядным и 32-разрядным достаточно мала. Поскольку никто не собирается запускать какие-либо варианты CLR для части с 32 КБ пространства кода и 4 КБ ОЗУ, кого волнует, сможет ли такой чип удовлетворить его гарантии.

Кстати, я думаю, было бы полезно иметь различные уровни возможностей, определенных в спецификации C; например, многие процессоры имеют 8-битные символы, которые можно объединить в более длинные слова с помощью объединений, и существует много практического кода, который использует это. Было бы хорошо определить стандарты для компиляторов, которые работают с такими вещами. Я также хотел бы видеть больше стандартов в нижней части системы, делая некоторые улучшения языка доступными для 8-битных процессоров. Например, было бы полезно определить перегрузки для функции, которая может принимать вычисляемое во время выполнения 16-разрядное целое число, 8-разрядную переменную или встроенную расширенную версию с константой. Для часто используемых функций эффективность может быть большой.

4 голосов
/ 30 сентября 2010

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

...