Резкое падение процессора с помощью программы C - PullRequest
0 голосов
/ 04 августа 2010

В моей программе резко падает производительность.В основном это пара вложенных циклов, которые выполняют операцию с парой наборов данных, а затем записывают результат.Проблема в том, что после 500 из 300 000 пар он замедляется с 0,07 секунды / пара до 5 секунд / пара, а загрузка ЦП снижается с почти 100% до ~ 4%.Вся используемая память выделяется перед вложенными циклами и освобождается после циклов.

Вот псевдокод, поэтому вы можете надеяться получить идею:

for (i=0; i<759; i++) {
   read_binary_data(data_file_1, data_1);
   read_binary_header(header_file_1, header_1);
   for (j=i+1; j<760;j++) {
      read_binary_data(data_file_2, data_2);
      read_binary_header(header_file_2, header_2);

      do_operation(data_1, data_2, out_data);
      update_header_data(header_1, header_2, out_header);

      write_binary_data_and_header(out_data, out_header);
   }
}

Я установил флаги синхронизации в начале и конце второго цикла for, чтобы увидеть приведенную выше синхронизациюно мне было интересно, могут ли быть лучшие варианты отладки, чтобы показать мне, почему работа замедляется.Пока я думал только о блокировке файловой системы, но я открываю только 5-6 файлов при каждом запуске, и каждый закрывается в конце своей подпрограммы.

Обновление в 22:15 по тихоокеанскому времени:
После различных тестов я обнаружил, что виновник, похоже, находится в части read_binary_data.Это может занять более 3 секунд для многих файлов.Я собираюсь попытаться упаковать все двоичные данные в 1 файл и прочитать все сразу, поэтому мне нужно только одно чтение.Бьюсь об заклад, у меня закончилась память, но это стоит тогоЯ думаю, что должно быть около 16 ГБ?).

Ответы [ 6 ]

5 голосов
/ 04 августа 2010

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

3 голосов
/ 04 августа 2010

Возможно, ваша запись в файл выполняется неэффективно, и по мере продвижения вам нужно делать все больше и больше запросов?

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

Иначе это могут быть ваши чтения.Трудно увидеть, как вы на самом деле выполняли файловые операции, но легко сделать это действительно дорогостоящим способом.

В любом случае, если у вас мало ЦП и мало памяти, у вас остается блокировкаОперации ввода / вывода!

2 голосов
/ 04 августа 2010

Первый к вашему актуальному вопросу - «C» не имеет опций отладки, связанных с производительностью ввода-вывода или любым другим видом производительности.Ваша IDE, отладчик или ОС могут, хотя, боюсь, я не знаю подробностей.

Глупый вопрос - все ли циклы дают одинаковое количество вывода?Возможно, первые 500 являются маленькими.

Возможно, 500 циклов - это время, необходимое для заполнения кеша записи на диск (на одном или нескольких уровнях - процесс, ОС, оборудование), и после этого программаI / O связан.На самом деле не могу сказать, вероятно ли это, не зная количества задействованных данных.

Попробуйте записать 1 ГБ данных в файл и рассчитайте время, чтобы получить очень приблизительное представление о том, какая приемлемая скорость вероятна.Если 0,07 секунды на пару, умноженное на количество данных на пару, работает быстрее, чем эта скорость, то ваша первоначальная быстрая скорость - это единственное специальное предложение: диск рано или поздно должен будет восстановиться.

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

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

Даже в этом случае 300000 * 5 секунд - это более 400 часов.Этого достаточно времени для любого простого смертного компьютера, чтобы записать весь свой жесткий диск много раз.Так что вам нужно сделать что-то довольно странное, чтобы сырая скорость записи была для этого единственной.

2 голосов
/ 04 августа 2010

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

  • Утечка памяти
  • Фрагментация памяти
  • Кэш насыщенности

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

0 голосов
/ 04 августа 2010

Вы делаете линейный поиск. Ваши данные хранятся в файле ??

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

0 голосов
/ 04 августа 2010

Если вы не выделите столько памяти, что система начнет подкачку, вы ограничены вводом / выводом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...