История изменений
Исправление 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.(операционная система должна знать о новых инструкциях, чтобы сохранять регистры и восстанавливать их при переключении контекста с одного процесса на другой.)
Windows 98SE знает про SSE регистры, так что можно использовать все SSE1, 2, 3, 4.1, 4.2 инструкции.
P.S.
-
Я для 3dnow использовал
__cpuid
вместо__cpuidex
потому что__cpuidex
нет в VS 2005, последней версии компилятора от Microsoft для Windows 98. -
Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 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.
-
Я для 3dnow использовал
__cpuid
вместо__cpuidex
потому что__cpuidex
нет в VS 2005, последней версии компилятора от Microsoft для Windows 98. -
Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 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.
-
Я для 3dnow использовал
__cpuid
вместо__cpuidex
потому что__cpuidex
нет в VS 2005, последней версии компилятора от Microsoft для Windows 98. -
Я не совсем понимаю зачем они там добавляют сравнение с вендором, кроме проверки 31 бита в EDX. Вроде этого не требуется, и также процессоры VIA лицензировали у AMD 3dnow…
в этой части кода:
static bool _3DNOW(void) { return CPU_Rep.isAMD_ && CPU_Rep.f_81_EDX_[31]; }