Страницы

Поиск по вопросам

Показаны сообщения с ярлыком cpu. Показать все сообщения
Показаны сообщения с ярлыком cpu. Показать все сообщения

среда, 4 марта 2020 г.

Остаток от деления с fmod

#php #double #cpu

Необходимо проверять кратность количества и коэффициента. Казалось, остаток от деления
должен быть 0, но нет, выводит некоторое значение. 

Почему? Как сделать, чтобы в таких случаях корректно считал? 

Сейчас сделал временное решение с round(fmod,5). 

$count = 46;
$k = 4.60;

echo fmod($count, $k);


Ответ 3.5527136788005E-15
    


Ответы

Ответ 1



Сегодня разбирали похожий случай с другой функцией и в другом языке, но имеющий причиной, фактически, то же самое: Непонятный результат при системном разделителе «точка» Как показали комментарии ниже, предложенный мною ранее вариант не дает 100%-ного профита. Тогда, с учётом всех комментариев, наверное, как-то так (прототип нашел у себя в include):

Ответ 2



Проблема связана с тем, как устроены числа с плавающей запятой. Начать с того, что 46 в двоичной системе может быть представлено точно, в то время как 4,6 — не может, и в действительности хранится как 4,59999999999999964472863211995. В вашем конкретном случае речь идёт об одной операции деления. Операции в стандарте IEEE 754 разработаны так, чтобы не вносить ошибку больше, чем половина ULP. (Это не относится к вычитанию, но углубляться не буду, поскольку здесь не вычитание). Значит, после единственного деления ошибка может отличаться от 0.0, но будет меньше, чем ULP/2. ULP (Unit in the Last Place) — единица в последнем знаке. Это не константа, она отличается для разных чисел, поэтому мы будем обозначать её ULP(x), то есть это функция от числа x. Нам надо посчитать ULP для остатка от деления 46 на 4,6. Поскольку результат сравним c 4,6 (то есть находится в диапазоне от 0 до 4,6) мы как раз хотим посчитать ULP(4,6). Двоичное представление числа 4,6 равно 1,00100110011001100110011001100110011001100110011001102×22. У чисел с двойной точностью под мантиссу выделено 52 бита, следовательно ULP(4.6) равно 0,00000000000000000000000000000000000000000000000000012×22. Константа слева от знака умножения называется машинным эпсилоном, она равна 2-52. Показатель степени 2 в формуле 22 — двоичная экспонента числа 4,6. В C/C++ для её вычисления можно вызывать функцию frexp, но в PHP её нет, так что надо заменить на floor(log10($x)/log10(2)). Сводим всё воедино. При вычислении остатка от деления $n на $m ошибка может составить ULP($m)/2. $epsilon = pow(2, -53); $binaryExponent = floor(log10(abs($m))/log10(2)); $ulp_m = $epsilon = pow(2, $binaryExponent); Вычислив остаток, сравниваем его с величиной ULP/2. Если он меньше, значит принимаем его равным нулю. $remainder = fmod($n, $m); if (abs($remainder) < $ulp_m/2) { $remainder = 0.0; } Я расставил в коде вызовы abs, чтобы он работал и с отрицательными числами тоже. Если вам нужно просто вывести число, забудьте всё, что написано выше и ограничьте количество выводимых цифр. sprintf('%.1f', fmod($n, $m))

четверг, 27 февраля 2020 г.

Алгоритм присваивания отрицательных значений какой-либо переменной в памяти

#java #операторы #cpu #ram #оператор_присваивания

К примеру, мне известно о том, что все отрицательные числа представляются в памяти
посредством дополнительного кода. Как это происходит? Русскоязычная терминология немного
отличается от той, которая была принята на Западе, поэтому было бы правильнее придерживаться
таких понятий, как первое (обратный код) и второе дополнения, чтобы не нарушать канонов.
С положительными значениями особых вопросов не возникает, так как прямой, обратный
и дополнительный код для этих значений абсолютно не отличается. А вот теперь мы и подошли
к первому вопросу. Меня интересует сам алгоритм присваивания отрицательных значений
какой-либо переменной. Поскольку я изучаю язык программирования Java, то хотелось бы
получить ответ именно в данном контексте (хотя я думаю, что для других языков разницы
также не будет, так как все операции физически осуществляются на уровне микропроцессора).
Правильно ли я понимаю, что за данное действие отвечает АЛУ (арифметико-логическое
устройство)? Или же какой-то другой блок процессора?

Здесь мне хотелось бы описать небольшой пример того, как я понимаю алгоритм присваивания
значения переменной. Допустим, что в нашем абстрактном коде имеется следующая инструкция: 

byte b = -5;


Изначально значение записывается в прямом коде, где старший бит является фиксированным
знаковым битом, который используется для кодирования знака числового значения в знаковых
типах данных. Получаем следующее двоичное представление: 

1000 0101


Затем мы получаем первое дополнение (обратный код). Для этого мы применяем инверсию
для каждого значащего разряда, которые участвуют в формировании самого числового значения.
Значение старшего разряда мы оставляем прежним. В результате инвертирования битов получаем
такой результат:

1111 1010


После чего мы добавляем к нашему результату 1, что и является вторым и результирующим
дополнением. В конечном итоге, в память будет помещено двоичное число, которое соответствует
числу -5 в десятичной системе счисления: 

1111 1011 


Но это всё лишь в моём представлении... Скажите, пожалуйста, насколько я прав? И
действительно ли обработкой всех этих операций занимается именно АЛУ? Если же я прав,
то значит ли это, что современные процессоры фактически не используют операцию вычитания
при арифметических расчётах? 

И еще вопрос, у меня уже давно возникла небольшая путаница с пониманием термина машинное
слово. В той же Википедии написано, что данная величина зависит от разрядности регистров
процессора. А от чего в свою очередь зависит эта разрядность? От типа данных в конкретном
языке программирования? Правильно ли я понимаю, что величина машинного слова типа byte
в языке программирования Java составляет 8 бит, short и char по 16 бит, а int 32 бита?
    


Ответы

Ответ 1



Да, смена знака в дополнительном коде производится инверсией битов и прибавлением единицы. как я понимаю алгоритм присваивания значения переменной Нет, не совсем так. Присваивание byte b = -5; не генерирует арифметических команд, только непосредственно присваивание значения 0xFB (-5). Любые арифметические выражения с константами сворачиваются на этапе компиляции. И действительно ли обработкой всех этих операций занимается именно АЛУ? Да, всей арифметикой занимается АЛУ, кто же еще. За исключением вычислений на этапе компиляции (которые в конечном итоге тоже выполняются АЛУ). значит ли это, что современные процессоры фактически не используют операцию вычитания при арифметических расчётах? Конечно, используют. Хотя вычитание можно выполнять в две команды - инверсия знака + сложение, одна команда вычитания выполняется быстрее. Но вот на уровне микропрограммы процессор может вычитание и не делать. И еще вопрос, у меня уже давно возникла небольшая путаница с пониманием термина машинное слово. В той же Википедии написано, что данная величина зависит от разрядности регистров процессора. А от чего в свою очередь зависит эта разрядность? Разрядность зависит от архитектуры процессора. У 32-разрядных процессоров машинное слово длиной 32 бита. У 64-разрядных соответственно 64 бита. Язык программирования тут не при чем, это аппаратная характеристика процессора.

Ответ 2



Главное преимущество дополнительного кода в том что сложение и вычитание работают одинаково как с положительными так и с отрицательными числами. -1 = 1111 1111 1 = 0000 0001 1 + 1 = 0000 0010 -1 + 1 = 0000 0000 -- из-за переполнения. -1 + -1 = 1111 1110

вторник, 28 января 2020 г.

Как работает процессор на уровне Физики? [закрыт]

#hardware #cpu

        
             
                
                    
                        
                            Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
                        
                        Закрыт 2 года назад.
                                                                                
           
                
        
Изучая C++ у меня возник вопрос, как устроен ПК и как так происходит, что он «понимает»
данные ему команды? То есть как он понимает, что 2+2=4, он же не человек? 
    


Ответы

Ответ 1



Если хотите узнать подробно, то советую почитать классический труд Тоненбаума - "Архитектура компьютера", где рассматриваются большинство уровней функционирования компьютера, начиная с самого низкого. Большинство схем ниже взяты оттуда. В современных компьютерах есть такой электрический элемент, как транзистор. Он представляет из себя элемент с тремя ножками: коллектор, базу, эммитер. Но суть в том, что он умеет в зависимости от сигнала на базу, выпускать ток или нет. Сигнал на базу поступает из различных внешних источников - намагниченная дорожка жесткого диска, проходящий луч лазера через CD-R или же замкнутый нажатой кнопкой на клавиатуре контакт. Не важно, главное, что у нас теперь есть два состояния - есть сигнал и нет сигнала. А теперь самое интересное, мы может комбинировать эти транзисторы и получить различные результаты на основе входящих на их базы сигналов. На самом деле вы же уже знакомы с булевой алгеброй, когда на вход подаются различные сигналы и получается в итоге другой? Ну так вот это оно и есть, это называется вентили. А это значит, что теперь у нас есть целый конструктор! И на этом конструкторе мы может создавать различные схемы, которые будут давать разный результат. Подали на базы различные сигналы и получили на выходе результат. Вот так выглядит схема сдвига и схема полусумматора. Объединив несколько полусумматоров, мы как раз получим побайтовое сложение чисел, о чем вы и спрашиваете в вопросе. Есть даже схемы, которые умеют хранить значение, так называемые защелки выполняющие роль памяти (RS-триггер). Как видите никакой магии, ну почти - на одном процессоре таких транзисторов умещается миллиарды... нет, не так - МИЛЛИАРДЫ! Это огромнейшее количество различных схем различной сложности и различного направления на паре квадратных сантиметров. Расчетом их упаковки на процессор как правило занимаются специальные программы, человеку это не под силу и создаются они с помощью высокоточной электроники. Сложно представимый научный прогресс в маленькой коробочке рядом с вами. В общем как-то так.

четверг, 23 января 2020 г.

Как происходит чтение страницы с диска при старте процесса?

#cpu #ram #виртуальная_память

Опишу конкретную ситуацию. 

При старте процесса CPU выдает виртуальный адрес. 

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

Вопрос: как с помощью виртуального адреса мы сможем извлечь с диска страницу? Ведь
мы не сможем просмотреть все страницы и найти по смещению информацию. А индекс в виртуальном
адресе нам не поможет. 
Как быть именно на старте процесса, когда TLB и PT пусты?
    


Ответы

Ответ 1



Что вы имеете ввиду под "процесс", если обычный процесс который работает под управлением операционной системы, то таблица страниц не будет пуста. При старте процесса операционная система прочитает в свои буфера начало выполнимого файла из заголовка, поймет какие сегменты и какого размера необходимо выделить для выполнения процесса, выделит блоки свободной оперативной памяти, построит таблицы страниц, при необходимости построит дескрипторные таблицы сегментов. После чего прочитает с диска необходимые блоки, подгрузит библиотеку загрузчика, который в свою очередь (с помощью функций ОС) догрузит необходимые библиотеки и настроит связи. После этого управление будет передано процессу, к этому моменту все таблицы уже будут существовать. А TLB будет просто очищен в момент передачи управления из ядра ОС в пространство процесса и набран CPU автоматически в процессе работы на основании информации из таблиц страниц. Обратите внимание, CPU сам не выдает никаких адресов, это делает операционная система, основываясь на своих собственных, внутренних таблицах трансляции адресов ОЗУ в адреса например swap раздела или файла отраженного на память.

воскресенье, 12 января 2020 г.

Измерить время выполнения одной инструкции

#cpu

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

Каждая инструкция состоит из нескольких составляющих ее операций, которые далеко
не факт что будут выполняться за одинаковое время - допустим, при fetching'е операнда
из памяти или на стадии Write back может произойти cache miss, и в итоге время доступа
вырастет очень существенно, от десятков наносекунд до микро или даже милисекунд.
Также на многих процессорах используются конвеерные оптимизации, т.е. опредленная
последовательность инструкций (паттерн) будет отрабатывать быстрее, нежели другой,
менее удачливый набор, опять-таки, из-за особенностей конвеера и стадий обработки инструкции.
Получается, это невозможно? 
Скажите, прав я или нет?
    


Ответы

Ответ 1



Да, всё зависит от огромного числа факторов, некоторые из которых Вы назвали. Я слышал, что intel'овские профайлеры умеют показывать некоторые подобные скрытые вещи (насколько я помню, - например, промахи кэша и ошибки предсказания переходов), используя знания об архитектуре и некоторые вещи эмулируя (а не измеряя).

пятница, 10 января 2020 г.

с чего начать разработку эмулятора процессора?

#java #ассемблер #информатика #cpu

Передо мной стоит вот такая задача: 
Разработать эмулятор процессора, создать для него язык ассемблера и написать несколько
программ. Нужно придумать свою архитектуру CPU и придумать ряд команд, почитайте про
современные архитектуры и например наборы команд SSE и AVX.

Помогите пожалуйста разобраться. Я понял так(хотя понимание пока очень поверхностное): 
Мне не надо напрямую возиться с регистрами и все такое? Главное на логическом уровне
все правильно сделать а не физическом? То есть можно взять любой ЯП, например Java,
и на нем писать процессор? Он не будет иметь ничего общего с физическими процессорами,
но по логике будем им соответствовать.  То есть у нас может быть программа, в которой
создан массив - наша эмуляция памяти, например так:  long[] memory = new long[1024
* 1024]. Еще один массив - эмулирет регистры. Наша основная программа стартует, создаются
оба массива, дальше она начинает считывать из заранее заготовленного файла по одной
строке. А вот в файле мы заранее напишем нашу систему команд - Логические - and, or,
not, xor. Численные - add, sub, mul, div. Программа будет их считывать и выполнять.
То есть в основной функции программы, которая считывает и выполняет команды, можно
будет написать switch если add -> складываем, если mul ->  умножаем  и т.д. Подскажите
пожалуйста, хотя бы направление мыслей правильное?
    


Ответы

Ответ 1



В целях обучения лучше взять простой процессор, который имеет задатки и много общего с реальными, но не настоящий - это 100%. В железе будет много оптимизации, которую вы не поймете и ограничений из-за жестокого реального мира, который не дает реализовать все так просто, как хотелось бы в теории. Нам профессор показал, как от простых бинарных операций дойти до С++. В конце (все кто сдали) с легкостью доказывали инвариантность С++ программ и логических состояний процессора по шагам. Но, боюсь, что без толкового преподавателя вам не обойтись. Посмотрите на этот пример, что бы просто понять, что такое ALU, вам нужно неплохо разбираться в дискретной математике. Работа с памятью не возможна без MUX DEMUX и знаний о них, что такое стэк и где хранится OP и т.д. Языки - это отдельная тема и очень обширная. Посмотрите на Computation Structures - Part 1 и Computation Structures - Part 2, я уверен - эти курсы дадут вам на порядок больше, нежели чем вы сами будете блуждать в бессистемных статьях вики и уж тем более тут. При все моем уважение к этому проекту, он абсолютно не академичен да и не стремится к этому. З.Ы. Вот тут хороший набор команд - из моих реликвий )

понедельник, 16 декабря 2019 г.

Как в программе узнать, есть ли в CPU Hyper-threading ?

#cpu #linux

Подозреваю, что это можно взять из /proc/cpuinfo, возможно из:
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36
clflush mmx fxsr sse sse2 ht syscall nx lm constant_tsc rep_good pni ssse3 lahf_lm

или из другого места (?), навскидку ничего больше из /proc/cpuinfo не подходит.
На первый взгляд флаг ht говорит о Hyper-threading. Но, это I5-2500, а в его описании
сказано, что 4 core без Hyper-Threading. Поэтому ht это скорее всего Hyper-Transport.
Здесь сказано, что Hyper-Threading это HTT/HT (видимо иногда метят по разному ?).
Собственно интересен также AMD аналог (не знаю как называется).
Никто не знает, что и где точно смотреть в Linux?    


Ответы

Ответ 1



Чтобы установить поддержку Hyper-Threading, нужно проверить CPUID (genuine Intel CPU) и значение бита № 28 регистра EDX (установлен в 1). По ссылке можно скачать утилиту CPUCount, которая как-то работает с Hyper-Threading.

Ответ 2



флаг ht действительно говорит о наличии у процессора возможности HyperThreading. есть поле cpu cores - оно говорит о числе реальных ядер, есть поле siblings - оно говорит о числе виртуальных ядер. По их соотношению можно узнать о наличии HyperThreading и о числе потоков на одно физическое ядро.

среда, 11 декабря 2019 г.

Парковка ядер процессора

#windows #cpu

В Интернете довольно популярная тема - как ОТКЛЮЧИТЬ парковку ядер (решение через
реестр обычно). А у меня стоит обратная задача: можно ли запарковать ядра ПРИНУДИТЕЛЬНО
и без перезагрузки операционной системы?

Update: Вот скачал программу и у меня при "игре" ползунками это вроде получилось,
но как это сделать самому программно?
    


Ответы

Ответ 1



Из комментария пользователя @nick_n_a: Если ядер «не хватает», всё равно идёт программная эмуляция нитей. Но у процессора также есть аппаратная поддержка нитей — Task-шлюзы. Думаю вам нужно почитать спецификацию процессора. Простейшая реализация — у каждого Task-шлюза есть AnifyMask, если сбросить у всех масок один бит, то ядро, соответствующее этому биту использоваться не будет. А вот общая маска для всех Task скорее всего хранится в ядре Windows и доступна на уровне драйвера. Возможно это можно найти дизассемблированием ядра, или его недокументироваными функциями. Всё равно с уровня приложения вам управлять процессором никто не позволит.

вторник, 10 декабря 2019 г.

Высокая загрузка процессора системой в Linux. Как узнать почему?

#linux #производительность #cpu


(источник: joxi.ru)

(источник: joxi.ru)    

Иногда имеем высокую загрузку процессора некими системными задачами.
Не процессами из userland, а именно "система" грузит.
Т.е. явно выполняются какие-то системные вызовы (выделение памяти, переключения контекста),
или работают драйверы (обрабатывают прерывания или что-то еще), идёт активный ввод-вывод. 

Это всё я всегда предполагаю, 
Но как узнать ТОЧНО, почему высокая загрузка - не представляю. Поэтому прошу помощи.  

Сейчас я использую несколько косвенных методов, но они не всегда подходят: глянуть
в iotop, прибвать процессы по одному, и смотреть не спала ли нагрузка.  

Но иногда просто нельзя останавливать сервисы. А иногда и процессов работающих уже
почти не осталось, а нагрузка всё равно есть. 

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


Ответы

Ответ 1



Вам надо сходить сюда, можете найти русский перевод или похожие статьи. Поможет вам ограничить выборочно потребление CPU процессами почитать про strace и подобные ему sudo strace -t -e trace=open,connect,accept unity сможете увидеть много интересного для ядра - ftrace или поищите еще kernel tracer-ов утилиты, которая дает понять это с одного взгляда я не знаю, если вы не нагуглите, я бы пошел следующим способом: настроить мониторинг процессов так, чтобы в случае возникновения нагрузки на K% на N секунд каким-либо процессом, он давал алерт. Можно наскриптовать так, чтобы при возникновении алерта, мониторинг натравливал trace на этот процесс, на секунду, допустим, и сохранял бы список самых часто выполняемых / долгих функций. Но тут нужно быть осторожным, чтобы не повалить систему и не заполнить hdd. Т.е. скриптинг должен учитывать, что необязательно ставить trace на процесс, который уже был под трейсом (т.е. для которого уже сохранен tracefile), иначе процессы начнут тормозить еще больше, к примеру. Нельзя трейсить слишком долго - гигабайтные дампы вам не нужны. Если вы решаете конкретную задачу борьбы с DDoS - ну, или очень много денег и очень много дц (повезло, если у вас есть), или cloudflare - я бы так пошел для начала. Т.е. тут все от задач зависит, дебажить драйвер ядра - один подход, защищаться от ddos - другой.

Ответ 2



Красная полоска говорит о io-wait или о прерываниях. Это работа драйверов и ядра. Откройте обычный top. Там будет строчка: %Cpu(s): 15,3 us, 1,4 sy, 0,0 ni, 78,8 id, 3,4 wa, 0,8 hi, 0,3 si, 0,0 st Если большое число перед wa - устройство ввода вывода работает медленней чем планировщик. Чаще всего это запись на мертвый жесткий диск, но также может проявляться при работе видеокарты (майнинг на gpu). Запись на сетевой диск. hi и si это прерывания. Часто встречал при сгоревшей сетевой карте. Дальше смотрим процессы в топе. Там или в квадратных скобках указан драйвер или без них. Что-то вроде kworker/u8:7+events_unbound, loop8 и прочее. Название указывает на что это такое и номер экземпляра. Покопавшись в /proc/, /sys/ можно сопоставить процесс с устройством. Стоит обратить внимания ещё и на обычные службы, которые могут хотеть от ядра слишком многого. Например, ускорение шифрования на урезанном процессоре. Но там обычно полоски наполовину зеленые, наполовину красные. Ещё такие фокусы могут быть на виртуалках, когда другая виртуалка кушает ресурсы.

среда, 27 ноября 2019 г.

Как связаны разрядность процессора, разрядность его регистров, размер адресуемой памяти и как все это влияет на быстродействие?

Изучаю архитектуру компьютера по книгам Танненбаума  и Харрис.

И все равно не понимаю многих вроде бы простых вещей. Вопросов много, но почти все они так или иначе связаны с машинным словом. Это самая непонятная для меня тема.

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


Как рязрядность процессора влияет на его быстродействие. Вроде как
64-разрядные быстрее чем 32-разрядные. Но почему? Не понимаю.
Приведу пример: Система команд для процессоров MIPS-32. Там ведь
сама архитектура команд такая, что все команды убираются в 32 бита.
То есть, если сделать 64 бита, старшие 32 бита придется просто
заполнить нулями. И что, процессор станет от этого быстрее?
Из Википедии: 


  разрядность процессора (разрядность его машинного слова). Машинное
  слово — машинно-зависимая и платформозависимая величина, измеряемая в
  битах или байтах (тритах или трайтах), равная разрядности регистров.


Почему машинное слово обязательно должно быть равно разрядности
регистров? Почему мы не можем читать данные по 64 бита за раз имея
16-разрядные регистры, например?
Теперь про память. Снова из Википедии:


  64-битный регистр способен хранить в себе одно из 264 = 18 446 744 073
  709 551 616 значений. Процессор с 64-битной адресацией памяти может
  напрямую обращаться к 16 ЭБ памяти.


Я понимаю что количество памяти зависит от адреса количества бит в
адресе. Но опять же, как это связано с регистрами? Я вижу только
одну связь: если мы собираемся хранить адреса в регистрах, то
регистры должны иметь ту же разрядность что и адреса. Но разве
обязательно хранить адреса в регистрах?
Про разрядность ОС я вроде понимаю, но хотелось бы уточнить. Как я
понимаю, ОС связана со всем этим так: 64-разрядная ОС работает на
64-разрядном процессоре, 32-разрядная - на 32-разрядном. То есть с
появлением 64-разрядного процессора было неизбежно появление
64-разрядной ОС. Правильно ли я понимаю это?
И вот тут вопрос скорее исторический, но так же очень важный для
меня. Я всегда считал что 64-разрядный процессор появился недавно и
это преподносилось как большой прорыв. А на Википедии вот что
написано: 


  Требования к точности научных вычислений возросли, и в 1974 году
  появилась первая машина с 64-битным словом — суперкомпьютер Cray-1

В чем вообще была сложность создать 64-разрядный процессор? И в чем
сейчас сложность создать, например, 128-разрядный процессор? От чего
это вообще зависит? Чем определяется? Разрядностью регистров? А в
чем сложность увеличить разрядность регистров? Чем она определяется?

    


Ответы

Ответ 1



Основная работа процессора заключается не в передаче информации, а в ее преобразовании Регистр - это та же оперативная память, но от которой идет прямая разводка к куче исполняющи устройств, которые производят арифметические и другие действия с данными. Этих лини делается очень много. На каждый разряд регистра будет свой и большой набор транзисторов для выполнения конкретных операций. Отсюда и сложность увеличения количества разрядов. При росте размерности регистра в 2 раза как минимум удваивается и объем всех исполняющих устройств. растет кристалл, растет тепловыделение. Посмотрите на систему команд, любые преобразования данных требуют участия как миниму одного регистра. А часть операций происходит исключительно в регистрах. В x86 архитектур можно добавить к регистру память. Но например нельзя произвести сдвиг или умножение ячейки памяти. нельзя сложить значения двух ячеек памяти не забрав предварительно одну из них в регистр. потому что исполнительный механизм данной операции имеет прямую разводку только с регистром. В: Почему мы не можем читать данные по 64 бита за раз имея 16-разрядные регистры Можем, но куда читать и зачем ? Вообще современные процессоры так и делают, заполняю внутренний кеш и оперируют при этом разрядностью шины, регистры тут не участвуют. Прочитал мы 64 бита в кеш, а теперь нам надо их умножить на 3, например. А регистр у нас 16 битный, как умножать ? Правильно, частями, применяя кучу дополнительных преобразований и тратя на это драгоценные такты. Поэтому размерность шины передачи вторична. Главное - это разрядность регистра. И это назвали машинным словом. В: Но разве обязательно хранить адреса в регистрах? Да, обязательно. Процессору как то надо сказать - возьми вот там данные. А там эт где ? В памяти ? А как тогда будет выглядеть инструкция - возьми адрес, находящийс по адресу, вон по тому адресу лежащему в инструкции ... А если нам надо работать подряд с блоком данных (мы в цикле обрабатываем массив) и этот адрес надо увеличивать (т.е. выполнять сложение, которое мы можем произвести только в регистре) Кстати, разрядность команды и разрядность процессора разные вещи. В MIPS упаковал все команды в 32 бита. А x86 платформа с незапамятных времен была с переменной разрядность операций. от коротких однобайтных, до длиннющих монстров с кучей префиксов. Разрядность процессора = разрядность регистра = максимальный размер обрабатываемой одной инструкцией информации (в обычных командах, из которых состоит основной код, всякие SSE не берем). Быстродействие - кто сказал, что разрядность играет ключевую роль. Да, разрядност влияет. Бум на 64 битные процессоры и ОС отличный пример маркетинга. 64 битный код част оказывается медленнее 32 битного. Если программе не надо адресовать более 4 Гб памяти а ее код хранит 64 битные адреса - то размер программы в 2 раза больше. Больше размер - дольше читать в кеш. Требуется больше памяти. Начинается гонка за гигабайтами оперативки ... Сейчас даже пошел обратный процесс. во всю развивается x32 ABI - работа 32 битного кода в 64 битном режиме. Но давайте возьмем RSA-шифрование, которое используется в том же повсеместном SSL Для него необходимы сложные расчеты с очень большими числами. Предположим, что у на нет специализированных инструкций процессора для него. Разумеется если процессор оперирует 64 битными регистрами он выполнит расчет в 2 раза быстрее, просто потому, что за один такт он способен обработать в 2 раза больше информации. Да, на расчетных задачах с большими числами выигрыш от увеличения разрядности сложно переоценить. В: 64-разрядная ОС работает на 64-разрядном процессоре, 32-разрядная - на 32-разрядном. Нет, 64 битная ОС состоит из 64 битного кода, способного адресовать память 64 битным адресами. Конечно она может это делать только на 64 битном процессоре. Появление О конечно было неизбежно. Хотя и тут маркетинг сыграл значительную роль. 90% разбирающег в компах народа считают, что для адресации свыше 4 Гб оперативной памяти на платформе intel нужна 64 Бит ОС. Да, в Windows было насильно введено такое ограничение. Процессоры Intel в 32 битном режиме PAE адресуют до 64 Гб оперативки, при этом правда один процесс ограничен 4 Гб. 32 Бит linux отлично себя чувствует с такими объемами. По поводу истории и сложности построения 128 битных регистров ... вопрос только цене. Да, на каких то системах не массового рынка это сделано давно, на массовом рынк было не нужно, вот и не появлялось. И тогда оно стоило баснословно, ибо как мы говорил в начале - каждый бит регистра - это куча исполняющих устройств, а при тех технология производства разместить на кристалле столько транзисторов было, скажем так, затруднительно. Полноценные 128 битные процессоры попросту не нужны, особенно для массового рынка, адресовать больше 64 ЭБ памяти, где бы ее еще найти. Вообще сейчас во всех процессорах intel есть 16 регистров SSE размером 128 бит, это не регистры общего назначения, они для расчетов. А на современных Xeon, предназначенных для серьезных вычислений, 32 регистра ZMM по 512 бит (см. AVX)...

Ответ 2



Я вижу только одну связь: если мы собираемся хранить адреса в регистрах, то регистры должны иметь ту же разрядность что и адреса. Чтобы окончательно вас запутать: Не должны. К примеру, восьмибитные процессоры умеют адресовать 16 бит: инструкция доступа памяти выбирает адрес не из регистра, а из регистровой пары. 8086-й процессор с 16-ю разрядными регистрами умеет адресовать 20 бит (базовый регистр << 4 + регистр смещения). Упомянутый Cray-1 имел 64-разрядные регистры данных и 24-разрядные регистры адреса.

Ответ 3



Всё относительно. К примеру, рас-параллеливание алгоритмов может выигрывать на процессорах с нескольким ядрами, но лишь в случае - если алгоритм поддаётся распараллеливанию. Т.е. если задачу можно разделить на две параллельные нити. Так же и с разрядностью процессора. Если алгоритм можно оптимизировать под большие регистры - то да, на x86_64 он будет выполняться быстрее, чем на i386. Но если сам алгоритм не поддаётся оптимизации и его скорость не зависит от размера регистра - то никакого ускорения Вы не получите.

среда, 17 июля 2019 г.

linux использует только часть процессоров

Имеется восьмипроцессорный сервер. Каждый процессор по 10 ядер, итого 80 физических ядер. ОС Oracle Linux Server release 6.7, ядро 3.8.13-98.2.1.el6uek.x86_64
Проблема в том, что ОС использует только два процессора из 8:

При этом lscpu, говорит что все ядра задействованы
Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 160 On-line CPU(s) list: 0-159 Thread(s) per core: 2 Core(s) per socket: 10 Socket(s): 8 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 47 Stepping: 2 CPU MHz: 2393.990 BogoMIPS: 4787.90 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 30720K NUMA node0 CPU(s): 0-159
Пробовал запустить strees -c 80, количество задействованных ядер не изменилось, только выросла la. Не знаю куда копать. Признателен за любую помощь. Спасибо.


Ответ

Было обновлено ядро ОС. В биосе выставил вручную количество задействованных ядер на CPU (опция Enhanced Processor Core Disable (Intel Core Select)).
После загрузки в ОС все ядра стали использоваться, stress -c 160, соответственно, нагрузил их все. Доподлинно сказать, что именно помогло не могу.
Всем спасибо за помощь.

вторник, 21 мая 2019 г.

Остаток от деления с fmod

Необходимо проверять кратность количества и коэффициента. Казалось, остаток от деления должен быть 0, но нет, выводит некоторое значение.
Почему? Как сделать, чтобы в таких случаях корректно считал?
Сейчас сделал временное решение с round(fmod,5).
$count = 46; $k = 4.60;
echo fmod($count, $k);
Ответ 3.5527136788005E-15


Ответ

Сегодня разбирали похожий случай с другой функцией и в другом языке, но имеющий причиной, фактически, то же самое: Непонятный результат при системном разделителе «точка»
Как показали комментарии ниже, предложенный мною ранее вариант не дает 100%-ного профита. Тогда, с учётом всех комментариев, наверное, как-то так (прототип нашел у себя в include):

суббота, 9 марта 2019 г.

Измерить время выполнения одной инструкции

Всем привет. Вот недавно возник такой вопрос. Вопрос носит характер удовлетворения скорее чистого любопытства, а не практический интерес, хотя, в-принципе, было бы и на практике интересно попробовать возможно ли такое проверить. В-общем, насколько я понимаю, такое невозможно на сегодняшних, современных процессорах (невозможно же?), так как Instruction pipeline на современных процах конвееризирован. Каждая инструкция состоит из нескольких составляющих ее операций, которые далеко не факт что будут выполняться за одинаковое время - допустим, при fetching'е операнда из памяти или на стадии Write back может произойти cache miss, и в итоге время доступа вырастет очень существенно, от десятков наносекунд до микро или даже милисекунд. Также на многих процессорах используются конвеерные оптимизации, т.е. опредленная последовательность инструкций (паттерн) будет отрабатывать быстрее, нежели другой, менее удачливый набор, опять-таки, из-за особенностей конвеера и стадий обработки инструкции. Получается, это невозможно? Скажите, прав я или нет?


Ответ

Да, всё зависит от огромного числа факторов, некоторые из которых Вы назвали. Я слышал, что intel'овские профайлеры умеют показывать некоторые подобные скрытые вещи (насколько я помню, - например, промахи кэша и ошибки предсказания переходов), используя знания об архитектуре и некоторые вещи эмулируя (а не измеряя).

суббота, 27 октября 2018 г.

Как в программе узнать, есть ли в CPU Hyper-threading ?

Подозреваю, что это можно взять из /proc/cpuinfo, возможно из: flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx lm constant_tsc rep_good pni ssse3 lahf_lm или из другого места (?), навскидку ничего больше из /proc/cpuinfo не подходит. На первый взгляд флаг ht говорит о Hyper-threading. Но, это I5-2500, а в его описании сказано, что 4 core без Hyper-Threading. Поэтому ht это скорее всего Hyper-Transport. Здесь сказано, что Hyper-Threading это HTT/HT (видимо иногда метят по разному ?). Собственно интересен также AMD аналог (не знаю как называется). Никто не знает, что и где точно смотреть в Linux?


Ответ

Чтобы установить поддержку Hyper-Threading, нужно проверить CPUID (genuine Intel CPU) и значение бита № 28 регистра EDX (установлен в 1). По ссылке можно скачать утилиту CPUCount, которая как-то работает с Hyper-Threading.

понедельник, 1 октября 2018 г.

Как связаны разрядность процессора, разрядность его регистров, размер адресуемой памяти и как все это влияет на быстродействие?

Изучаю архитектуру компьютера по книгам Танненбаума и Харрис
И все равно не понимаю многих вроде бы простых вещей. Вопросов много, но почти все они так или иначе связаны с машинным словом. Это самая непонятная для меня тема.
Хочу оговориться, что я понимаю, что между разрядностью процессора, разрядностью регистров, размером адресуемой памяти и быстродействием компьютера существует прямая связь. Я не понимаю почему так.
Как рязрядность процессора влияет на его быстродействие. Вроде как 64-разрядные быстрее чем 32-разрядные. Но почему? Не понимаю. Приведу пример: Система команд для процессоров MIPS-32. Там ведь сама архитектура команд такая, что все команды убираются в 32 бита. То есть, если сделать 64 бита, старшие 32 бита придется просто заполнить нулями. И что, процессор станет от этого быстрее? Из Википедии:
разрядность процессора (разрядность его машинного слова). Машинное слово — машинно-зависимая и платформозависимая величина, измеряемая в битах или байтах (тритах или трайтах), равная разрядности регистров.
Почему машинное слово обязательно должно быть равно разрядности регистров? Почему мы не можем читать данные по 64 бита за раз имея 16-разрядные регистры, например? Теперь про память. Снова из Википедии:
64-битный регистр способен хранить в себе одно из 264 = 18 446 744 073 709 551 616 значений. Процессор с 64-битной адресацией памяти может напрямую обращаться к 16 ЭБ памяти.
Я понимаю что количество памяти зависит от адреса количества бит в адресе. Но опять же, как это связано с регистрами? Я вижу только одну связь: если мы собираемся хранить адреса в регистрах, то регистры должны иметь ту же разрядность что и адреса. Но разве обязательно хранить адреса в регистрах? Про разрядность ОС я вроде понимаю, но хотелось бы уточнить. Как я понимаю, ОС связана со всем этим так: 64-разрядная ОС работает на 64-разрядном процессоре, 32-разрядная - на 32-разрядном. То есть с появлением 64-разрядного процессора было неизбежно появление 64-разрядной ОС. Правильно ли я понимаю это? И вот тут вопрос скорее исторический, но так же очень важный для меня. Я всегда считал что 64-разрядный процессор появился недавно и это преподносилось как большой прорыв. А на Википедии вот что написано:
Требования к точности научных вычислений возросли, и в 1974 году появилась первая машина с 64-битным словом — суперкомпьютер Cray-1 В чем вообще была сложность создать 64-разрядный процессор? И в чем сейчас сложность создать, например, 128-разрядный процессор? От чего это вообще зависит? Чем определяется? Разрядностью регистров? А в чем сложность увеличить разрядность регистров? Чем она определяется?


Ответ

Основная работа процессора заключается не в передаче информации, а в ее преобразовании. Регистр - это та же оперативная память, но от которой идет прямая разводка к куче исполняющих устройств, которые производят арифметические и другие действия с данными. Этих линий делается очень много. На каждый разряд регистра будет свой и большой набор транзисторов для выполнения конкретных операций. Отсюда и сложность увеличения количества разрядов. При росте размерности регистра в 2 раза как минимум удваивается и объем всех исполняющих устройств. растет кристалл, растет тепловыделение.
Посмотрите на систему команд, любые преобразования данных требуют участия как минимум одного регистра. А часть операций происходит исключительно в регистрах. В x86 архитектуре можно добавить к регистру память. Но например нельзя произвести сдвиг или умножение ячейки памяти. нельзя сложить значения двух ячеек памяти не забрав предварительно одну из них в регистр. потому что исполнительный механизм данной операции имеет прямую разводку только с регистром.
В: Почему мы не можем читать данные по 64 бита за раз имея 16-разрядные регистры
Можем, но куда читать и зачем ? Вообще современные процессоры так и делают, заполняют внутренний кеш и оперируют при этом разрядностью шины, регистры тут не участвуют. Прочитали мы 64 бита в кеш, а теперь нам надо их умножить на 3, например. А регистр у нас 16 битный, как умножать ? Правильно, частями, применяя кучу дополнительных преобразований и тратя на это драгоценные такты. Поэтому размерность шины передачи вторична. Главное - это разрядность регистра. И это назвали машинным словом.
В: Но разве обязательно хранить адреса в регистрах?
Да, обязательно. Процессору как то надо сказать - возьми вот там данные. А там это где ? В памяти ? А как тогда будет выглядеть инструкция - возьми адрес, находящийся по адресу, вон по тому адресу лежащему в инструкции ... А если нам надо работать подряд с блоком данных (мы в цикле обрабатываем массив) и этот адрес надо увеличивать (т.е. выполнять сложение, которое мы можем произвести только в регистре)
Кстати, разрядность команды и разрядность процессора разные вещи. В MIPS упаковали все команды в 32 бита. А x86 платформа с незапамятных времен была с переменной разрядностью операций. от коротких однобайтных, до длиннющих монстров с кучей префиксов. Разрядность процессора = разрядность регистра = максимальный размер обрабатываемой одной инструкцией информации (в обычных командах, из которых состоит основной код, всякие SSE не берем).
Быстродействие - кто сказал, что разрядность играет ключевую роль. Да, разрядность влияет. Бум на 64 битные процессоры и ОС отличный пример маркетинга. 64 битный код часто оказывается медленнее 32 битного. Если программе не надо адресовать более 4 Гб памяти, а ее код хранит 64 битные адреса - то размер программы в 2 раза больше. Больше размер - дольше читать в кеш. Требуется больше памяти. Начинается гонка за гигабайтами оперативки ... Сейчас даже пошел обратный процесс. во всю развивается x32 ABI - работа 32 битного кода в 64 битном режиме.
Но давайте возьмем RSA-шифрование, которое используется в том же повсеместном SSL. Для него необходимы сложные расчеты с очень большими числами. Предположим, что у нас нет специализированных инструкций процессора для него. Разумеется если процессор оперирует 64 битными регистрами он выполнит расчет в 2 раза быстрее, просто потому, что за один такт он способен обработать в 2 раза больше информации. Да, на расчетных задачах с большими числами выигрыш от увеличения разрядности сложно переоценить.
В: 64-разрядная ОС работает на 64-разрядном процессоре, 32-разрядная - на 32-разрядном.
Нет, 64 битная ОС состоит из 64 битного кода, способного адресовать память 64 битными адресами. Конечно она может это делать только на 64 битном процессоре. Появление ОС конечно было неизбежно. Хотя и тут маркетинг сыграл значительную роль. 90% разбирающего в компах народа считают, что для адресации свыше 4 Гб оперативной памяти на платформе intel нужна 64 Бит ОС. Да, в Windows было насильно введено такое ограничение. Процессоры Intel в 32 битном режиме PAE адресуют до 64 Гб оперативки, при этом правда один процесс ограничен 4 Гб. 32 Бит linux отлично себя чувствует с такими объемами.
По поводу истории и сложности построения 128 битных регистров ... вопрос только в цене. Да, на каких то системах не массового рынка это сделано давно, на массовом рынке было не нужно, вот и не появлялось. И тогда оно стоило баснословно, ибо как мы говорили в начале - каждый бит регистра - это куча исполняющих устройств, а при тех технологиях производства разместить на кристалле столько транзисторов было, скажем так, затруднительно. Полноценные 128 битные процессоры попросту не нужны, особенно для массового рынка, адресовать больше 64 ЭБ памяти, где бы ее еще найти. Вообще сейчас во всех процессорах intel есть 16 регистров SSE размером 128 бит, это не регистры общего назначения, они для расчетов. А на современных Xeon, предназначенных для серьезных вычислений, 32 регистра ZMM по 512 бит (см. AVX)...