Разбираюсь. Как сохранить результаты выполнения команды по указателям? Код (C): void cpuinfo(int code, int *_eax, int *_ebx, int *_ecx, int *_edx) { __asm { mov eax, code cpuid mov [_eax], eax mov [_ebx], ebx mov [_ecx], ecx mov [_edx], edx } }
Хм хм, вроде, разобрался. Код (C): void cpuinfo(int code, int *_eax, int *_ebx, int *_ecx, int *_edx) { __asm { mov eax, code cpuid mov esi, _eax; mov [esi], eax mov [_ebx], ebx mov [_ecx], ecx mov [_edx], edx } }
Почему код 0x80000005 на моем компьютере может возвращать четыре нуля в регистрах? Этот код должен возвращать размер L1 кэша данных в первых восьми битах регистра ECX. Код (C): void cpuinfo(int code, int *_eax, int *_ebx, int *_ecx, int *_edx) { __asm { mov eax, code cpuid mov esi, _eax mov [esi], eax mov esi, _ebx mov[esi], ebx mov esi, _ecx mov [esi], ecx mov esi, _edx mov [esi], edx } } const int MASK_LSB_8 = 0xFF; int get_cache_line_size() { int eax = 0, ebx = 0, ecx = 0, edx = 0; cpuinfo(0x80000005, &eax, &ebx, &ecx, &edx); return ecx & MASK_LSB_8; } int main() { std::cout << get_cache_line_size() << std::endl; return 0; }
Потому что сначала надо убедиться, поддерживается эта функция или нет, а потом уже вызывать её. Ну и такой вот код очень подозрителен в плане качества: Код (Text): __asm { mov eax, code cpuid mov esi, _eax mov [esi], eax mov esi, _ebx mov[esi], ebx mov esi, _ecx mov [esi], ecx mov esi, _edx mov [esi], edx } А вы уверены, что у вас параметры, например, не в регистрах передаются? Потому что если в регистрах - всё это будет прекрасно попорчено командой cpuid.
http://www.flounder.com/cpuid_explorer2.htm#CPUID(2) Правильно понимаю, что информация о дата кэше первого уровня для интел получается с аргументом 2 и находится с 24 по 31 бит?
Качаем Intel software developers manual volume 2. Тыц: https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf Открываем, ищем команду CPUID, и читаем до просветления.
Aoizora, Код (C): int GetCacheSize(int cache_level) { // Intel stores it's cache information in eax, with ecx as index // The information received is as following: // ebx[31:22] = Ways of associativity // ebx[21:12] = Physical line partitions // ebx[11: 0] = Line size int cpuInfo[4]; __cpuidex(cpu_info, 4, cache_level); // Index 0 is L1 data cache int ways = cpu_info[1] & 0xffc00000; // This receives bit 22 to 31 from the ebx register ways >>= 22; // Bitshift it 22 bits to get the real value, since we started reading from bit 22 int partitions = cpu_info[1] & 0x3ff800; // This receives bit 12 to 21 partitions >>= 12; // Same here, bitshift 12 bits int line_size = cpu_info[1] & 0x7ff; // This receives bit 0 to 11 int sets = cpu_info[2]; // The sets are the value of the ecx register // All of these values needs one appended to them to get the real value return (ways + 1) * (partitions + 1) * (line_size + 1) * (sets + 1); // Calculate the cache size by multiplying the values } для тех кто в танке Пользуйтесь