21

(7 відповідей, залишених у Pascal/Delphi)

А ще можна степеневу функцію в ряд розложити і порахувати результат до якої тобі точності треба))

22

(17 відповідей, залишених у C#, .NET)

mich_retten написав:

Тобто у Вас є список, який Ви хочете обробляти декількома потоками, при цьому змінювати. Так?
Ви не можете цього зробити (надійно) з зв'язаним списком, бо msdn стверджує, що клас не є потокобезпечним (thread safe):

The LinkedList<T> class does not support chaining, splitting, cycles, or other features that can leave the list in an inconsistent state. The list remains consistent on a single thread. The only multithreaded scenario supported by LinkedList<T> is multithreaded read operations.
тобто Ви не можете змінювати такий список у потоках.

Підемо від простого: Ви маєте список з 4х елементів, два потоки "одержали" по два елементи (так ми гадаємо).
Перший поток вирішив, що треба видалити елемент після останнього (у його частки), а другий - видалити елемент перед першим (з його частки). Що повинно відбутися? Синхронізації у Вас не передбачено (якщо виключити цю маґічну змінну "go").
Може, розбити цей список на декілька автономних, обробити в потоках, а потім злити в один?
Я не знаю повністю Вашої задачі, просто спробую навести Вас самого на якесь прийнятне рішення.

Тим не менше, проблема ж зараз не в цьому, я не шукаю як обійти цю проблему, я шукаю як її вирішити.
Та й такі випадки, як Ви навели, дуже малоймовірні у мому випадку.
Синхронізацію я робитиму свою
Ви певно могли і не помітити, але

Також я хочу, щоб всі потоки почали роботу після "роздачі завдань", тобто передачі параметрів (для уникнення стану гонки). Якщо тут є кращий спосіб - кажіть

(Я знаю вумні слова)))))

23

(17 відповідей, залишених у C#, .NET)

mich_retten написав:

Може, такий трік виправить ситуацію, але не певен. Спробуйте:

                threads[i] = Task.Run(() => {
                            LinkedListNode<Homosapien> arg = first;
                            MakeStepForPopulation_thread(arg, interval);
                        });

робив, не виправило

24

(17 відповідей, залишених у C#, .NET)

mich_retten написав:

Ви просто забули, що тут:

 MakeStepForPopulation_thread(first, interval);

і тут:

first = current;

змінна first - той самий об'єкт. На момент початку виконання, мабуть, він вказує на 5-й елемент Вашої population.
Якщо хочете щось подібне реалізувати, кожет потік повинен одержати власну копію, яку тільки він може змінювати, незалежно від інших трейдів.

Бачте но, є 2 "але"
1. вони і мають отримувати власну копію, у локальну змінну. змінна в головному циклі змінюється, але ссилка на якийсь вузол копіюється в параметр методу (тобто мало б так бути, але так не є)
2. робив варіант без потоків, тоді все працювало, тобто зміна змінної у методі не змінювала змінної у головному циклі

Щоб позбавитись головного болю та не блукати у власному лабіринті, забудьте тут про ноди, простота - ґарантія безпеки:

Homosapien[] homoarray = population.ToArray();

, і MakeStepForPopulation_thread одержує цей масив, індекс початку для даного трєйда та кількість елементів для обробки.

Тут теж є своє "але"... під час обробки списку здійснюється його зміна (додавання-видалення елементів), для масиву так не вийде, плюс дууууже довгий цей список (1 000 000 елементів)

25

(17 відповідей, залишених у C#, .NET)

Ну ладно, про той випадок забули, зараз наступне:

        public void MakeStepForPopulation()
        {
            LinkedListNode<Homosapien> current = population.First;//мій список
            LinkedListNode<Homosapien> first;

            long interval = population.Count / THREAD_COUNT;
            go = false;//кажу, щоб жоден поток не почав свою роботу
            for (int i = 0; i < THREAD_COUNT - 1; i++)
            {//проходить роздача параметрів потокам
                first = current;
                for (long j = 0; j < interval; j++)
                    current = current.Next;

                threads[i] = Task.Run(() =>
                        {
                            MakeStepForPopulation_thread(first, interval);
                        });
            }
//останній потік в мене особливий, має починатись так
            threads[THREAD_COUNT - 1] = Task.Run(() =>
            {
                MakeStepForPopulation_thread(current, -1);
            });
//даю добро потокам
            go = true;
//чекаю потоки
            Task.WaitAll(threads);
        }

//власне, що роблять потоки
        public void MakeStepForPopulation_thread(LinkedListNode<Homosapien> current, long interval)
        {//тут потоки чекають
            while (!go)
                System.Threading.Thread.Sleep(10);

            LinkedListNode<Homosapien> next;
//тут іде обробка списку
            while (!(interval == 0 || current == null))
            {
                next = current.Next;
//MakeStep описаний повідомленням вище. Там є кілька особливих операцій, які змінюють головний список.
                current.Value.MakeStep(
                    GetMatrixConversion(current.Value.Age.Year,
                                        today.Month));
//відраховується лічильник
                interval--;
                current = next;
            }
        }

Тут є список елементів, я хочу розбити цей список на THREAD_COUNT, та пустити частини у обробку.
Наприклад, є список 1 2 3 4 5 6 7 8, THREAD_COUNT = 4, інтервал стане рівний 2 (по 2 елементи на поток), і мало б у перший поток на вхід податись (1, 2), на другий (3, 2), на третій (5, 2), і на останній (7, -1) (зроблено для того, щоб останній поток проходив не кокретну кількість елементів, а просто йшов до кінця, на це є певні причини).

Також я хочу, щоб всі потоки почали роботу після "роздачі завдань", тобто передачі параметрів (для уникнення стану гонки). Якщо тут є кращий спосіб - кажіть

Так от, в чому проблема. Проблема в тому, що по факту 3 потоки почались із 5 (а мали із 1 3 5), і один із 7. Тобто - перші три потоки брали параметри в циклі, де

                threads[i] = Task.Run(() =>
                        {
                            MakeStepForPopulation_thread(first, interval);
                        });

ну і останній брався окремо, то й получив все правильно. змінна first вийшла для всіх однаковою, ось в цьому проблема. В момент роздачі параметрів вона була різною. Чому так і як від цього позбутись?

26

(17 відповідей, залишених у C#, .NET)

Є в мене ділянка коду, яку я хочу розпаралелити (зараз вона працює правильно)

LinkedListNode<Homosapien> current = population.First;
            LinkedListNode<Homosapien> next;
            
            while (current != null)
            {
                next = current.Next;

                current.Value.MakeStep(
                        GetMatrixConversion(current.Value.Age.Year,
                                            today.Month));                

                current = next;
            }

Додаткова інформація: MakeStep іноді викидує подію, що current помер, тоді він видаляється зі списку:

        public void MakeStep(double[][] Prob)
        {
            if (hystori.Last.Value.state == State.Dead)
                throw new InvalidOperationException("Individ is dead");

            State newState = (State)(GetRandIndex(Prob[(int)hystori.Last.Value.state]));

            if (newState != hystori.Last.Value.state)
            {
                hystori.AddLast(new Record(newState, today));
            }

            today.MoveNext();
            age.MoveNext();
            
            if (newState != State.Dead)
            {
                CanBorn();
            }
            else
            {
                RaiseImDie();
            }
        }

Розбив список, припустимо, на 4 частини, кожну пустив у потік, викинуло помилку, мов я оброблюю мертвого індивіда... Ні, проблема не в тому, що я покаліцьки розбив список, бо наступний код викидує ту ж помилку

            while (current != null)
            {
                next = current.Next;
                Task.Factory.StartNew(() =>
                {
                    current.Value.MakeStep(
                        GetMatrixConversion(current.Value.Age.Year,
                                            today.Month));
                });
                current = next;
            }

Питання - якого дива два потоки заходять в один об'єкт, коли я їм не кажу цього робити?

27

(4 відповідей, залишених у Пропоную роботу)

Я можу, номер картки казати?

28

(13 відповідей, залишених у C#, .NET)

Я це зробив)))))

http://s17.postimg.org/wnxfg1d7z/Untitled.png

Спрацювало коли сказав студії компілювати конкретно 64-бітну версію програми
+ можливо в app.config рядок, який я описав вище, що стосується GC

P.S. я не працюю з жорстким, це підкачка включилась

29

(13 відповідей, залишених у C#, .NET)

quez написав:

Щось нагуглив, може якось допоможе.

Чому ви моделюєте захворюваність для 42 млн, а не для двох-трьох тисяч?

лінк не повний

Ну це ніби стрес-тест)) у мене все чудово працює для 100 000, і на них я і будуватиму звіт

30

(13 відповідей, залишених у C#, .NET)

Arete написав:

P.S. якщо брати по 100 000 - то це вийде пристойно довше, включається вибір між часом і пам'яттю

Від конкретної задачі залежить - структура даних, дії над цими даними - наприклад, алгоритми сортування Merge та QuickSort, з вами не згодні.

Основні операції що виконуються - перебір(постійно) та додавання-видалення(10% всіх операцій). З огляду на це я вибрав структуру даних LinkedList, про що вказав у топі треду.
Шановний Arete, спростити задачу я собі і сам зможу. Мене не цікавить зараз як зробити так, щоб воно займало менше пам'яті, я просто обмежу вхідні дані та й по всьому.
Мене цікавить чому викидається ця помилка, чому я не можу використовувати весь вільний простір оперативної пам'яті

31

(13 відповідей, залишених у C#, .NET)

Arete написав:

vitia444

А що саме ви робите з таким списком? Може дані можна розбити на частини і обробляти частинами? Наприклад:

брати 100 000 народу на 10 років

а потім наступні 100 000 народу.

Взагалі - можна, але хочеться просто для саморозвитку знайти в чому проблема і щоб воно брало весь розмір оперативки

P.S. якщо брати по 100 000 - то це вийде пристойно довше, включається вибір між часом і пам'яттю

32

(67 відповідей, залишених у Робота)

При розподілі важливості 40% на скіли, 40% на особисті якості і 20% на остальне - шановний @funivan, у Вас половина резюме відсутня

Раджу всім-всім-всім (навіть досвідченим) ось цю статтю. Вона велика, але після останнього редагування свого резюме пропозиції так і сиплються (а сам без досвіду роботи)

33

(4 відповідей, залишених у Пропоную роботу)

На тому сайті, де взята задача, можна подивитись хто її вже рішив і надіслати їм повідомлення

34

(1 відповідей, залишених у C#, .NET)

Так у Вас же всі кнопки не прописані

35

(13 відповідей, залишених у C#, .NET)

koala написав:

На Stackoverflow кажуть, що the maximum size of a CLR Object is 2gb even on 64bit. Хоча за логікою це не має стосуватися LinkedList. А взагалі - щось дивне робите.

    <runtime>
      <gcAllowVeryLargeObjects enabled="true" />
    </runtime>

Цей рядок (який стосувався безпосередньо числа 2Gb) не допомагає

36

(13 відповідей, залишених у C#, .NET)

Ах да, забув одразу відповісти всім цікавим:

Програма моделює захворюваність 42 000 000 людей протягом 10 років (така задача, але і одного року змоделювати не може). Якщо брати 100 000 народу на 10 років, то там лише 40 Мб і все. Коли для 100 000 народу на 1000 років - то до 400 Мб доходило

P.S. цікаво, як зробити так, щоб пам'ять використовувалась вся, а не лише якийсь певний розмір

37

(13 відповідей, залишених у C#, .NET)

Маю програму, вона вилітає через System.OutOfMemoryException після того як розмір використовуваної пам'яті досягає 1600 МБ, при цьому не важливо, скільки саме вільно оперативки. Я так розумію десь стоїть обмеження, як його обійти/відмінити?

P.S. дані зберігаю у LinkedList, Windkws x64 8.1

38

(23 відповідей, залишених у Робота)

fed_lviv написав:

Дякую,Q-bart
JAVA (Lviv):
- SoftServe (пробував: по програмуванню пройшов, по english - ні)
- GlobalLogic (проходив тестування, набагато важче ніж у SoftServe, але там курси, а тут Trainee, для співбесіди потрібно було набрати більш 50 %, набрав 48% - і тут english мене підкачав)
- Sigma Software (ex-Sigma Ukraine) (щось нове , але: "Чтобы попасть на практику, необходимо подать заявление своему руководителю практики в вузе" , не навчаюсь, а працюю)

А можна детальніше про стажування у GL? Я якось там рився, раніше бачив, а вже - ні... Плюс недавно якось мене туди запросили на співбесіду по стажуванню (але не тести)...
P.S. .NET

using System;

namespace Ex06
{
    class Program
    {
        static int[][] A;
        static int[][] B;
        static int rowsAtA;
        static int columnsAtA;
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            // TODO: Implement Functionality Here
            FillA();
            ShowA();
            B = GetB(A);
            ShowB();
            SortA();
            ShowA();
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
        /// <summary>
        /// Заповнити масив A
        /// </summary>
        static void FillA()
        {
            Console.Clear();
            Console.WriteLine("Введiть кiлькiсть рядкiв i стовпчикiв матрицi:");
            columnsAtA = rowsAtA = int.Parse(Console.ReadLine());
            
            Random rand = new Random();

            A = new int[rowsAtA][];
            for (int i = 0; i < rowsAtA; i++)
            {
                A[i] = new int[columnsAtA];
                for (int j = 0; j < columnsAtA; j++)
                {
                    //+1 гарантує відсутність нулів
                    A[i][j] = rand.Next(columnsAtA) + 1;
                }

                //перевірка щоб перший елемент рядка був менший останнього
                if (A[i][0] > A[i][columnsAtA - 1])
                {
                    int tmp = A[i][0];
                    A[i][0] = A[i][columnsAtA - 1];
                    A[i][columnsAtA - 1] = tmp;
                }
            }

        }

        static int[][] GetB(int[][] A)
        {
            int[][] B = new int[rowsAtA][];

            int currentColumnsCount;

            for (int i = 0; i < rowsAtA; i++)
            {
                currentColumnsCount = A[i][columnsAtA - 1] - A[i][0] + 1;
                B[i] = new int[currentColumnsCount];

                for (int j = 0; j < currentColumnsCount; j++)
                {
                    //не зебуваємо, що нумерація з 0, тому третій стовпчик насправді 2-ий
                    B[i][j] = A[i][A[i][0] - 1 + j];
                }
            }

            return B;
        }


        /// <summary>
        /// вивід матриці на дисплей
        /// </summary>
        static void ShowA()
        {
            // вивід матриці на дисплей
            Console.WriteLine("Вмiст матрицi A:");
            for (int i = 0; i < rowsAtA; i++)
            {
                for (int j = 0; j < columnsAtA; j++)
                {
                    Console.Write("{0, 4}", A[i][j]);
                }
                Console.WriteLine();
            }
        }

        static void ShowB()
        {
            Console.WriteLine("---Матриця B--");
            for (int i = 0; i < B.GetLength(0); i++)
            {
                for (int j = 0; j < B[i].Length; j++)
                    Console.Write("{0, 4}", B[i][j]);

                if (B[i].Length > 0)
                    Console.WriteLine();
            }
            Console.WriteLine("---Матриця B--");
        }

        static void SortA()
        {
            for (int i = 0; i < rowsAtA; i++)
            {
                Array.Sort(A[i]);
            }
        }
    }
}

Стосовно того, що працює правильно - ну це знаєте, все-одно що здорову людину прив'язати до інвалідного візка. Ну а що - пересуватися ж може))

P.S. NullReferenceException - це не ділення на нуль, це означає, що посилання B (а В саме як посилання на певну ділянку пам'яті інтерпретується) нікуди не вказує, а Ви з того "нікуди" хочете щось дістати.

40

(11 відповідей, залишених у Pascal/Delphi)

Assign, Rewrite