Страницы

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

понедельник, 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 и о числе потоков на одно физическое ядро.

Синхронизация потоков с главным потоком приложения

#c_sharp #net #многопоточность


Есть модель приложения:


объекты-задачи, которые выполняются в бесконечном цикле, информируя об результатах
своей работы - пока их не информировали об прекращении работы;
элемент пользовательского интерфейса (ЕПИ), который отображает информацию о результатах
работы объектов-задач;


Вот код объекта-задачи:

public class DataItem
{
    public int Index { get; set; }

    public string Value { get; set; }

    public object locker { get; set; }
}

public class Task
{
    private DataItem dataItem { get; set; }
    public EventWaitHandle local { get; set; }
    public EventWaitHandle exit { get; set; }
    Action refreshAction { get; set; }

    public Task (DataItem dataItem, Action refreshAction, EventWaitHandle localEvent,
EventWaitHandle exitEvent)
    {
        this.dataItem = dataItem;
        exit = exitEvent;
        local = localEvent;
        this.refreshAction = refreshAction;
    }

    public void Procees ()
    {
        local.WaitOne();
        Random n = new Random();
        while (!exit.WaitOne(0, false)) {
            lock (dataItem.locker) {
                string s = 0.ToString("D10").Remove(dataItem.Index, 1).Insert(dataItem.Index,
"x");
                dataItem.Index = dataItem.Index == 9 ? 0 : dataItem.Index + 1;
                dataItem.Value = s;
            }
            refreshAction();
            Thread.Sleep(n.Next(5, 25) * 100);
        }
        local.Set();
    }
}


И вот код "наблюдающего" обьекта:

class Main
{
    public EventWaitHandle main = new ManualResetEvent(false);

    private void create ()
    {
        main.Reset();
        foreach (DataItem item in data) {
            item.locker = ((ICollection)data).SyncRoot;
            EventWaitHandle local = new AutoResetEvent(false);
            EventArray.Add(local);
            new Thread(new Task(item, RefreshGrid, local, main).Procees).Start();
            local.Set();
        }
        foreach (AutoResetEvent are in EventArray) {
            are.Set();
        }
    }

    private void stop ()
    {
        main.Set();
        bool l = true;
        while (l) {
            AutoResetEvent[] events = EventArray.Cast().ToArray();
            l = WaitHandle.WaitAll(events);
        }
    }
}


Объект-задача, помимо сообщения о закрытии работы, сообщает о том, что он остановил
работу, что приложению необходимо для нормального закрытия. И вот в чем загвоздка -
несмотря на то, что объект-задача получает сообщение о закрытии работы и сообщает об
остановке, то главное окно не реагирует на сообщения от задач, это я делаю через 

l = WaitHandle.WaitAll(events);


Почему не реагирует? Может, такой подход неправильный? Что порекомендуете?
    


Ответы

Ответ 1



Когда вы делаете WaitAll - вы блокируете вызывающий поток (в котором GUI). Поэтому окно ни на что не реагирует. Уберите отслеживание состояния и ожидания в фоновый поток, а в GUI только отображайте состояние и передавайте команды.

Инициализация свойств контрола без перерисовки

#c_sharp #winforms #net #visual_studio


Привет, Хэшкод!
Я создаю контрол, наследуясь от UserControl. К нему добавляю свойство, от которого
зависит внешний вид контрола.
Теперь внимание, если присваивать это свойство в коде конструктора формы сразу после
InitializeComponent(), то сначала пользователь увидит форму такой, как она выглядела
у меня в режиме «дизайна мышкой», и уже после этого контрол перересуется в нужный мне
вид. Плохо.
Пометить свойство с помощью BrowsableAttribute я тоже не могу, ибо тип свойства —
мой собственный класс, настраивать который среда не умеет. Плохо.
Как же сделать так, чтобы инициализация свойства произошла между первыми form1.SuspendLayout()
и form1.ResumeLayout(false)?

В идеале хотелось бы иметь возможность писать код, непосредственно в поля окошка
«свойства». Например если свойство имеет тип MyClass, то в соответсвующее поле из окна
«свойства» я бы написал new MyClass(param1, param2).    


Ответы

Ответ 1



В .Net есть возможность создания своих редакторов свойств контрола на основе UITypeEditor, что как раз даст возможность изменять свойство контрола через свой пользовательский интерфейс. Ссылки по теме: Класс UITypeEditor Статья: Creating Custom Controls - Providing Design Time Support Пошаговое руководство. Реализация редактора типов пользовательского интерфейса

Инвентарь браузерной игры в двоичном массиве

#алгоритм #php #разработка_игр


Есть динамический двумерный массив.
Есть база итемов.
Итем может занимать произвольное количество ячеек массива.
У итема есть параметр [координаты], где указаны координаты ячейки, где находится
левый-верхний угол итема и дополнительно указаны его длинна и высота.
Примерно вот такая схема имеется ввиду.

В данном случае: [crossbow:2-2:2:4].
Для переноса итема юзается drag-n-drop. НО, так как в базе инвентаря фактически итем
находится в координатах одной клетки, то итемы элементарно накладываются один на другой. 
А если итем приходит извне, то инвентарь вообще не генерируется: система проверяет
записи координат, делает поправки x+width, y+height и вставляет итем в пустое место,
если оно есть. Но такие проверки очень монструозны и затратны, так как все поправки
должны упасть во временное хранилище занятых клеток и не учитываться при проверке на
их свободность.
Можно подпереть костылём с другой стороны: при каждоё операции с инвентарём отсылать
в базу новую версию маски занятых секторов в массиве, но тесты показали, что 4 человека
усиленно переставляя итемы в инвентаре ложат нахрен всю базу и выедают непростительно
много памяти.
Кто-то разрабатывал подобные системы? Решал подобные проблемы? Каким макаром такое
можно оптимизировать? Или может я не замечаю какой нить более простой подход к теме?    


Ответы

Ответ 1



Пример из камента: Есть (слева) инвентарь (занятые - 1, пустые - 0), 10х5 И есть (справа) предмет, допустим на данный момент в позиции [7;2], размером 2х3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 При их сложении получится следующее: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 1 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 Тут мы видим двойку - это значит, предметы накладываются и сюда поставить нельзя. Накидал вам простенькую функцию подстановки предмета в матрицу. Вам остается только сложить массивы и проверить в сумме наличие двоек :) Соответственно, при "добавлении в инвентарь" вам надо пробежаться по инвентарю и поискать в нем такие места, при добавлении предмета в которые этих самых двоек не возникает. function getItemMatrix( $item /* x, y, w, h */ ) { $invWidth = 10; $invHeight = 5; $result = array(); if ($item->x + $item->w > $invWidth or $item->y + $item->h > $invHeight) return false; // сюда ставить нельзя for ($i = 1; $i <= $invWidth; $i++) { $result[$i] = array(); for ($j = 1; $j <= $invHeight ; $j++) $result[$i][$j] = ($i >= $item->x and $i <= $item->x + $item->w and $j >= $item->y and $j <= $item->y + $item->w ) ? 1 : 0; } return $result; } /* - Аааа, я видел двойку! - Успокойсся, Бендер, это был сон, двоек не бывает... © futurama */

Как сделать таймаут при вводе пароля?

#php #защита #взлом


Хочу сделать защиту от перебора паролей (метод «грубой силы») в моей системе на PHP
для Панели Администратора.
У меня уже стоит CAPTCHA, но это не защищает.
Хочу сделать таймаут. Ввел 5 раз не правильно пароль — отдыхай 12 часов.
Проблема вот в чем: просто так отследить компьютер-то не получается, IP у многих
динамичный, а Cookie легко удаляются. Писать в БД «для всех» тоже не хорошо: вдруг
кто-то просто так захочет побаловаться, а администратор потом будет сутки ждать.
Есть, конечно, другой вариант: ставить таймаут после каждого ввода пароля секунд
на 5, так, чтобы сильно замедлить брутфорс + можно после 100 неправильных паролей отсылать
на email владельцу сайта письмо, мол, пытаются взломать.
Что Вы думаете об этом?    


Ответы

Ответ 1



После первой неудачной попытки авторизации в час «проверяйте» пароль секунд 5-10 перед тем, как сообщить верный ли он. Пользователя при входе кидает на промежуточную страницу «минуточку, проверяем пароль», которая обновится только через 10 секунд и только тогда будет известно, вошли мы или нет. Обновил страницу раньше — продолжаешь ждать. Для этого на сервере, при каждой попытке авторизации: Проверяем время последней неудачной попытки входа. Если дальше, чем час назад — переходим к п.5. Запоминаем в сессии время начала запроса. Отдаем страницу «пожалуйста, подождите», которая всеми средствами (, javascript, ручная ссылка «обновить») обновляет себя. При каждом обращении смотрим, прошло ли 10 секунд с начала операции. Если не прошло — см. п.3, если нет — п.5. Выдаем результат авторизации, если успешно — логиним пользователя, если нет — запоминаем время неуспешной авторизации и назад на форму входа и от нее снова начиная с п.1. Брутфорс на скорости в меньше десятка паролей в минуту быстро перестанет быть интересным. Легитимный пользователь же подождет свои 10 секунд и успешно залогинится. Всякое security through obscurity типа входа по GET-параметрам не рекомендую. Оно будет или не сильно полезным или вредным (ссылка для входа останется в истории браузера и будет регулярно вылезать автокомплитом — прекрасная вещь для демонстрации гостям).

Ответ 2



Во первых стоит сделать защиту от чрезмерно частых запросов страниц. Во вторых предложу такой вариант: записывать в файл или еще куда id пользователей и время подбора и удваивайте таймаут ввода пароля вплоть до 24х часов. Данный способ рекомендовали на хабре но для несколько других целей.

Ответ 3



Динамический IP - на самом деле небольшая сказка. Он по факту не меняется при каждом переподключении, даже на диалапе (который, как я думаю, отсутствует в наше время). Плюс можно использовать уникальный ключ (md5 от юзерагента, IP, еще каких-либо данных)

Ответ 4



Панель администратора говоришь? Ну как вариант переместить админку, т.е. поменяй урл, старый можешь оставить, но чтоб всегда неправильный пароль писал. Если капчу обходят, то поменяй капчу на более сложную, на рекапчу например, порой самому трудно прочитать что там написано. Капча в основном помогает от ботов, но и от живого брутера поможет, который через пару десяток капч бросит сие занятие.

Ответ 5



Давно писал такую штуку, покопайте session_start(); $time = time(); ### Разрешать запросы # Не чаще чем $max_n = 5; # раз # за $max_t = 10; # секунд if(empty($_SESSION['ban']['time'])){ $_SESSION['ban']['time'] = $time; } if(empty($_SESSION['ban']['rate'])){ $_SESSION['ban']['rate'] = 1; } if($_SESSION['ban']['time']+$max_t < $time){ unset($_SESSION['ban']); echo 'true'; }else{ if($_SESSION['ban']['rate'] > $max_n){ echo 'false'; }else{ $_SESSION['ban']['rate']++; echo 'true'; } }

Ответ 6



А ещё вот так можно сделать: Как защитить админку сайта? То есть - вход только по get запросу. Если его нет - тогда пусть выходит чистая страница. И так вообще не понятно будет что это такое.

Треугольники Python

#python #фракталы




Нужно чтобы вначале рисовался треугольник, внутри него еще 3, внутри трех еще 3 и
так далее. 

Как это реализуется?
    


Ответы

Ответ 1



Вот вам псевдокод: SierpinskiSieve(v1, v2, v3, recdepth) : if (recdepth == 0) : draw triangle (v1, v2, v3) return m1 = (v2 + v3)/2 m2 = (v3 + v1)/2 m3 = (v1 + v2)/2 SierpinskiSieve(v1, m3, m2, recdepth - 1) SierpinskiSieve(m3, v2, m1, recdepth - 1) SierpinskiSieve(v2, m1, v3, recdepth - 1)

Ответ 2



Моя версия с использованием turtle, может кому-то пригодится. l это длина стороны треугольника, n это количество рекурсивно нарисованных треугольников Серпиского. Например >>>sierpinski(100,1) даст результат как на третьей картинке из вопроса. from turtle import * speed("fastest") def sierpinski(l,n): assert (isinstance(l, int) or isinstance(l, float)) and l>0, 'parameter l is a positive float or integer' assert isinstance(n, int) and n>=0, 'parameter n is a whole number' if n==0: for i in range(0,3): fd(l) left(120) else: sierpinski(l/2,n-1) fd(l/2) sierpinski(l/2,n-1) bk(l/2) left(60) fd(l/2) right(60) sierpinski(l/2,n-1) left(60) bk(l/2) right(60)

Ускoрение суффикснoгo автoмaтa

#c #дерево #cpp #теория_автоматов


Имеется суффиксный автомат. Необходимо найти самую длинную пoдстpoку (oбщyю).
Автомат реализован на основе данной статьи: Суффиксный автомат.
(если с суффиксным автоматом не знакомы или статью не смотрели, дальше можно не читать)
Работает быстрее Хорспула. Но при работе с длинными строками скорости всё равно недостаточно.
Может кто-нибудь работал с подобной структурой и знает, как её можно ускорить?    


Ответы

Ответ 1



Из известных сейчас данных можно сделать вывод, что асимптотически улучшить ничего нельзя, 500000 тысяч раз выполнять O(5*1000) с маленькой скрытой константой даст таки 4-5 секунд. Остается попробовать уменьшить эту константу. 1) if (state.next[DELIM_FIRST + i] != 0) ... for (int i = 0; i < ALPHABET; i++) { if (state.next[CHAR_FIRST + i] != 0) { так делать не совсем верно в плане быстродействия. map::operator[] вставляет элемент при его отсутствии, а значит появятся пустые переходы, в которых нет необходимости. Нужно что то такое: if (state.next.find(DELIM_FIRST + i) != state.next.end()) а тут просто перебор: for (std::map::const_iterator i = state.next.begin(); i!= state.next.end(); ++i) { ... Так немного ускорим обработку, убрав заранее ненужные операции. 2) Раз строк для поиска всего 5, state::result можно сделать std::bitset или свою битовую маску на базе char/int. 3) В реализации из оригинальной статьи используется std::map для хранения переходов. Это дает экономию памяти и быстрый перебор, но требует логарифмическое время на нахождение перехода. Переходы эти можно сделать обычным массивом, это даст честную константу на поиске, но придется перебирать отсутствующие переходы при переборе (в старой версии статьи об этом было написано, не знаю почему убрали) struct state { int len, link; int next[ALPHABET_SIZE]; }; На деле в столь маленькой std::map будет больше оверхэда (на поддержание дерева), и она будет работать помедленнее массива. Имеет смысл поменять и посмотреть (Если сделать так, совет #1 будет неверен). Еще можно поменять на хэш-таблицу. Не исключены также оптимизации исходящие из структуры входных данных. UPD. 4) Присваивание лучше конечно убрать, вместо оператора суммы для состояния сделать operator | (это семантически вернее отражает действие), внутри битовый OR для маски.