Можно ли иметь условный код во время выполнения, основанный на архитектуре процессора? - PullRequest
4 голосов
/ 25 октября 2011

Я использую .Net 4.5 (предпросмотр ... 4 подходит для целей этого вопроса).Я занимаюсь многопоточностью.

Основываясь на своих исследованиях, я знаю, что процессоры x86 имеют сильную модель памяти, что означает, что записи не будут переупорядочены.Это делает освобождение замков безопасным.Это не относится к процессорам Itanium, которые имеют слабую модель памяти.

Я понимаю изменчивость, барьеры памяти и принципы переупорядочения выполнения.

В идеале мне нужно вставить барьеры памяти в ключочки , если , то процессор Itanium, но не если это x86.Возможно ли сделать это динамически, как в директивах компилятора времени выполнения, которые обрабатывает JIT?

Если нет, я понимаю, что мне понадобятся отдельные сборки для двух платформ.В таком случае, каков самый элегантный способ сделать это, не имея 2 набора файлов C #, а просто изменив цель?

Ответы [ 2 ]

1 голос
/ 26 октября 2011

В ответ на ваш главный вопрос; Я не думаю, что в настоящее время возможно, чтобы инструкции CIL были условно скомпилированы с машинными инструкциями на основе платформы (кроме того, что было запечено в компиляторе JIT).

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

1 голос
/ 25 октября 2011

Я понятия не имею, поможет ли это вам или нет, но есть несколько вариантов, описанных в этом ответе:

В другом ответе кто-то предоставил ссылку на следующий пример кода (из Paint.NET) для определения архитектуры ОС.Вы можете внести незначительную корректировку, чтобы включить проверку IA64:

private enum Platform
{
    X86,
    X64,
    Unknown
}

internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
internal const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;

[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
    public ushort wProcessorArchitecture;
    public ushort wReserved;
    public uint dwPageSize;
    public IntPtr lpMinimumApplicationAddress;
    public IntPtr lpMaximumApplicationAddress;
    public UIntPtr dwActiveProcessorMask;
    public uint dwNumberOfProcessors;
    public uint dwProcessorType;
    public uint dwAllocationGranularity;
    public ushort wProcessorLevel;
    public ushort wProcessorRevision;
};

[DllImport("kernel32.dll")]
internal static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);        

private static Platform GetPlatform()
{
    SYSTEM_INFO sysInfo = new SYSTEM_INFO();
    GetNativeSystemInfo(ref sysInfo);

    switch (sysInfo.wProcessorArchitecture)
    {
        case PROCESSOR_ARCHITECTURE_AMD64:
            return Platform.X64;

        case PROCESSOR_ARCHITECTURE_INTEL:
            return Platform.X86;

        default:
            return Platform.Unknown;
    }
}
...