LINUX.ORG.RU

История изменений

Исправление fsb4000, (текущая версия) :

Да. Наверное.

Я вот такую функцию использую.

bool is_3dnow_supported() {
    int cpu_info[4];

    // Проверяем, поддерживает ли процессор инструкцию CPUID
    __cpuid(cpu_info, 0);
    // Проверяем, что EAX > 0
    if (cpu_info[0] <= 0) {
        return false;
    }

    // Получаем информацию о расширениях процессора
    __cpuid(cpu_info, 0x80000000);

    // Проверяем, что EAX >= 0x80000001
    if (cpu_info[0] < 0x80000001) {
        return false;
    }

    // Получаем информацию о поддерживаемых расширениях
    __cpuid(cpu_info, 0x80000001);

    // Проверяем наличие 3DNow! (бит 31 в EDX)
    return (cpu_info[3] & (1 << 31)) != 0;
}

Вообще есть функция IsProcessorFeaturePresent: Тогда так:

if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE)) {
  optimized_fun();
} else {
  generic_fun();
}

Но я не пользуюсь IsProcessorFeaturePresent для 3dnow, потому что эта функция из NTKernel. В Windows 98 есть эта функция, но лишь как заглушка(всегда возвращает 0).

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent

Ещё есть такая страница, где показано как определять все инструкции процессора: https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170#example

Но нужно иметь ввиду, что AVX и AVX2 инструкции поддерживаются лишь с Windows 7 SP1, а AVX512 с Windows 10.(операционная система должна знать о новых инструкциях, чтобы сохранять регистры и восстанавливать их при переключении контекста с одного процесса на другой.)

Windows 98SE знает про SSE регистры, так что можно использовать все SSE1, 2, 3, 4.1, 4.2 инструкции.

P.S.

  1. Я для 3dnow использовал __cpuid вместо __cpuidex потому что __cpuidex нет в VS 2005, последней версии компилятора от Microsoft для Windows 98.

  2. Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 31 бита в EDX. Вроде этого не требуется, и также процессоры VIA лицензировали у AMD 3dnow…

в этой части кода:

static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }

Исправление fsb4000, :

Да. Наверное.

Я вот такую функцию использую.

bool is_3dnow_supported() {
    int cpu_info[4];

    // Проверяем, поддерживает ли процессор инструкцию CPUID
    __cpuid(cpu_info, 0);
    // Проверяем, что EAX > 0
    if (cpu_info[0] <= 0) {
        return false;
    }

    // Получаем информацию о расширениях процессора
    __cpuid(cpu_info, 0x80000000);

    // Проверяем, что EAX >= 0x80000001
    if (cpu_info[0] < 0x80000001) {
        return false;
    }

    // Получаем информацию о поддерживаемых расширениях
    __cpuid(cpu_info, 0x80000001);

    // Проверяем наличие 3DNow! (бит 31 в EDX)
    return (cpu_info[3] & (1 << 31)) != 0;
}

Вообще есть функция IsProcessorFeaturePresent: Тогда так:

if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE)) {
  optimized_fun();
} else {
  generic_fun();
}

Но я не пользуюсь IsProcessorFeaturePresent для 3dnow, потому что эта функция из NTKernel. В Windows 98 есть эта функция, но лишь как заглушка(всегда возвращает 0).

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent

Ещё есть такая страница, где показано как определять все инструкции процессора: https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170#example

Но нужно иметь ввиду, что AVX и AVX2 инструкции поддерживаются лишь с Windows 7 SP1, а AVX512 с Windows 10.(операционная система должна знать о новых инструкциях, чтобы сохранять регистры и восстанавливать их при переключении контекста с одного процесса на другой.)

SSE инструкции поддерживаются начиная с Windows 98SE.

P.S.

  1. Я для 3dnow использовал __cpuid вместо __cpuidex потому что __cpuidex нет в VS 2005, последней версии компилятора от Microsoft для Windows 98.

  2. Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 31 бита в EDX. Вроде этого не требуется, и также процессоры VIA лицензировали у AMD 3dnow…

в этой части кода:

static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }

Исходная версия fsb4000, :

Да. Наверное.

Я вот такую функцию использую.

bool is_3dnow_supported() {
    int cpu_info[4];

    // Проверяем, поддерживает ли процессор инструкцию CPUID
    __cpuid(cpu_info, 0);
    // Проверяем, что EAX > 0
    if (cpu_info[0] <= 0) {
        return false;
    }

    // Получаем информацию о расширениях процессора
    __cpuid(cpu_info, 0x80000000);

    // Проверяем, что EAX >= 0x80000001
    if (cpu_info[0] < 0x80000001) {
        return false;
    }

    // Получаем информацию о поддерживаемых расширениях
    __cpuid(cpu_info, 0x80000001);

    // Проверяем наличие 3DNow! (бит 31 в EDX)
    return (cpu_info[3] & (1 << 31)) != 0;
}

Вообще есть функция IsProcessorFeaturePresent: Тогда так:

if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE)) {
  optimized_fun();
} else {
  generic_fun();
}

Но я не пользуюсь IsProcessorFeaturePresent для 3dnow, потому что эта функция из NTKernel. В Windows 98 есть эта функция, но лишь как заглушка(всегда возвращает 0).

Ещё есть такая страница, где показано как определять все инструкции процессора: https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170#example

Но нужно иметь ввиду, что AVX и AVX2 инструкции поддерживаются лишь с Windows 7 SP1, а AVX512 с Windows 10.(операционная система должна знать о новых инструкциях, чтобы сохранять регистры и восстанавливать их при переключении контекста с одного процесса на другой.)

SSE инструкции поддерживаются начиная с Windows 98SE.

P.S.

  1. Я для 3dnow использовал __cpuid вместо __cpuidex потому что __cpuidex нет в VS 2005, последней версии компилятора от Microsoft для Windows 98.

  2. Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 31 бита в EDX. Вроде этого не требуется, и также процессоры VIA лицензировали у AMD 3dnow…

в этой части кода:

static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }