Ускорение цикла с использованием многопоточности в C # (Вопрос)

<!DOCTYPE html>
<html>
    <body>
        <p id="p1">
            <b>Enter the no of row and column to create table:</b>
            <br/><br/>
            <table>
                <tr>
                    <th>No. of Row(s) </th>
                    <th>No. of Column(s)</th>
                </tr>
                <tr>
                    <td><input type="text" id="row" value="4" /> X</td>
                    <td><input type="text" id="col" value="7" />Y</td>
                </tr>
            </table>
            <br/>
            <button id="create" onclick="create()">create table</button>
        </p>
        <br/><br/>
        <input type="button" value="Reload page" onclick="reloadPage()">
        <script>
            function create() {
                var row = parseInt(document.getElementById("row").value);
                var col = parseInt(document.getElementById("col").value);

                var tablestart="<table id=myTable border=1>";
                var tableend = "</table>";
                var trstart = "<tr bgcolor=#ff9966>";
                var trend = "</tr>";
                var tdstart = "<td>";
                var tdend = "</td>";
                var data="data in cell";
                var str1=tablestart + trstart + tdstart + data + tdend + trend + tableend;
                document.write(tablestart);

                for (var r=0;r<row;r++) {
                    document.write(trstart);
                    for(var c=0; c<col; c++) {
                        document.write(tdstart+"Row."+r+" Col."+c+tdend);
                    }
                }

                document.write(tableend);
                document.write("<br/>");
                var s="<button id="+"delete"+" onclick="+"deleteTable()"+">Delete top Row </button>";
                document.write(s);
                var relod="<button id="+"relod"+" onclick="+"reloadPage()"+">Reload Page </button>";
                document.write(relod);
            }
            function deleteTable() {
                var dr=0;
                if(confirm("It will be deleted..!!")) {
                    document.getElementById("myTable").deleteRow(dr);
                }
            }
            function reloadPage(){
                location.reload();
            }
        </script>
    </body>
</html>
13
задан Keith 19 September 2008 в 12:21
поделиться

6 ответов

Вы могли попробовать Параллельные расширения (часть.NET 4.0)

, Они позволяют Вам писать что-то как:

Parallel.Foreach (ListOfStrings, (item) => 
    result.add(CalculateSmth(item));
);

, Конечно, result.add должен был бы быть ориентирован на многопотоковое исполнение.

17
ответ дан Tobi 19 September 2008 в 12:21
поделиться

Обратите внимание, что параллелизм волшебно не дает Вам больше ресурса. Необходимо установить то, что замедляет CalculateSmth.

, Например, если это является зависящим от ЦП (и Вы находитесь на одноядерном) тогда то же количество галочек ЦП перейдет к коду, выполняете ли Вы их последовательно или параллельно. Плюс Вы получили бы немного служебные от управления потоками. Тот же аргумент относится к другим ограничениям (например, ввод-вывод)

, Вы только получите увеличение производительности в этом, если CalculateSmth оставит ресурс свободным во время его выполнения, которое могло бы использоваться другим экземпляром. Это весьма распространено. Например, если задача включает IO, сопровождаемый некоторым материалом ЦП, то обработайте 1, мог бы делать материал ЦП, в то время как процесс 2 делает IO. Как циновки указывает, цепочка единиц производителя-потребителя может достигнуть этого, если у Вас есть инфраструктура.

12
ответ дан slim 19 September 2008 в 12:21
поделиться

Необходимо разделить работу, которую Вы хотите сделать параллельно. Вот пример того, как можно разделить работу в два:

List<string> work = (some list with lots of strings)

// Split the work in two
List<string> odd = new List<string>();
List<string> even = new List<string>();
for (int i = 0; i < work.Count; i++)
{
    if (i % 2 == 0)
    {
        even.Add(work[i]);
    }
    else
    {
        odd.Add(work[i]);
    }
}

// Set up to worker delegates
List<Foo> oddResult = new List<Foo>();
Action oddWork = delegate { foreach (string item in odd) oddResult.Add(CalculateSmth(item)); };

List<Foo> evenResult = new List<Foo>();
Action evenWork = delegate { foreach (string item in even) evenResult.Add(CalculateSmth(item)); };

// Run two delegates asynchronously
IAsyncResult evenHandle = evenWork.BeginInvoke(null, null);
IAsyncResult oddHandle = oddWork.BeginInvoke(null, null);

// Wait for both to finish
evenWork.EndInvoke(evenHandle);
oddWork.EndInvoke(oddHandle);

// Merge the results from the two jobs
List<Foo> allResults = new List<Foo>();
allResults.AddRange(oddResult);
allResults.AddRange(evenResult);

return allResults;
5
ответ дан Hallgrim 19 September 2008 в 12:21
поделиться

Параллельные расширения прохладны, но это может также быть сделано только при помощи пула потоков как это:

using System.Collections.Generic;
using System.Threading;

namespace noocyte.Threading
{
    class CalcState
    {
        public CalcState(ManualResetEvent reset, string input) {
            Reset = reset;
            Input = input;
        }
        public ManualResetEvent Reset { get; private set; }
        public string Input { get; set; }
    }

    class CalculateMT
    {
        List<string> result = new List<string>();
        List<ManualResetEvent> events = new List<ManualResetEvent>();

        private void Calc() {
            List<string> aList = new List<string>();
            aList.Add("test");

            foreach (var item in aList)
            {
                CalcState cs = new CalcState(new ManualResetEvent(false), item);
                events.Add(cs.Reset);
                ThreadPool.QueueUserWorkItem(new WaitCallback(Calculate), cs);
            }
            WaitHandle.WaitAll(events.ToArray());
        }

        private void Calculate(object s)
        {
            CalcState cs = s as CalcState;
            cs.Reset.Set();
            result.Add(cs.Input);
        }
    }
}
18
ответ дан noocyte 19 September 2008 в 12:21
поделиться

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

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

Этот способ, которым многопоточность ограничена просто теми пятью потоками, и они будут все должны проделать работу вплоть до стека, пусто.

Вещи думать о:

  • Помещенная защита во входном и выходном списке, таком как взаимное исключение.
  • , Если порядок важен, удостоверьтесь, что выходной порядок поддержан. Один пример мог быть должен сохранить их в SortedList или чем-то как этот.
  • Удостоверяются, что CalculateSmth ориентирован на многопотоковое исполнение, что он не использует глобального состояния.
1
ответ дан Mats Fredriksson 19 September 2008 в 12:21
поделиться

Первый вопрос, на который необходимо ответить, состоит в том, необходимо ли использовать поточную обработку

, Если функциональный CalculateSmth () является в основном Зависящим от ЦП, т.е. тяжелым в использовании ЦП и в основном никаком I/O-usage, то мне нелегко видеть точку использования потоков, так как потоки будут конкурировать по тому же ресурсу, в этом случае ЦП.

, Если Ваш CalculateSmth () использует и ЦП и ввод-вывод, то это могла бы быть точка в использовании поточной обработки.

я полностью соглашаюсь с комментарием к своему ответу. Я сделал ошибочное предположение, что мы говорили о единственном ЦП с одним ядром, но в эти дни у нас есть многоядерные центральные процессоры, мое плохое.

2
ответ дан Mats Wiklander 19 September 2008 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: