Пожалуйста, скажите мне, что не так с моей резьбой! - PullRequest
1 голос
/ 11 мая 2010

У меня есть функция, позволяющая сжимать кучу файлов в один сжатый файл. Это занимает много времени (для сжатия), поэтому я попытался реализовать многопоточность в своем приложении. Скажем, если у меня есть 20 файлов для сжатие, я разделил это как 5 * 4 = 20, чтобы сделать это, у меня есть отдельные переменные (которые используются для сжатия) для всех 4 потоков, чтобы избежать блокировок, и я буду ждать, пока 4 потока не завершатся .. Теперь .. потоки работают, но я не вижу улучшения в их производительности. Обычно это занимает 1 минуту для 20 файлов (например) после реализации потоков ... разница только в 5 или 3 секунды, иногда такая же. здесь я покажу код для 1 потока (так же, как для других 3 потоков)

//main thread   
    myClassObject->thread1 = AfxBeginThread((AFX_THREADPROC)MyThreadFunction1,myClassObject);
    ....

    HANDLE threadHandles[4];
    threadHandles[0] = myClassObject->thread1->m_hThread;
    ....

    WaitForSingleObject(myClassObject->thread1->m_hThread,INFINITE);

UINT MyThreadFunction(LPARAM lparam)
{

    CMerger* myClassObject = (CMerger*)lparam;
    CString outputPath = myClassObject->compressedFilePath.GetAt(0);//contains the o/p path
    wchar_t* compressInputData[] = {myClassObject->thread1outPath,
                    COMPRESS,(wchar_t*)(LPCTSTR)(outputPath)};
    HINSTANCE loadmyDll;
    loadmydll = LoadLibrary(myClassObject->thread1outPath);
    fp_Decompress callCompressAction = NULL;
    int getCompressResult=0;
    myClassObject->MyCompressFunction(compressInputData,loadClient7zdll,callCompressAction,myClassObject->thread1outPath,
                    getCompressResult,minIndex,myClassObject->firstThread,myClassObject);
    return 0;
}

1 Ответ

3 голосов
/ 11 мая 2010

Во-первых, вы ожидаете только одного из потоков. Я думаю, что вы хотите WaitForMultipleObjects.

Что касается нехватки ускорения, считали ли вы, что фактическим узким местом является НЕ сжатие, а загрузка файла? Загрузка файла идет медленно, и 4 потока, конкурирующие за временные интервалы жесткого диска, «могут» даже привести к снижению производительности.

Вот почему преждевременная оптимизация - это зло. Вам необходимо выполнить профиль, профиль и профиль снова, чтобы определить, где находятся ваши РЕАЛЬНЫЕ узкие места.

Изменить: Я не могу комментировать ваши WaitForMultipleObjects, если я не вижу код. У меня никогда не было с этим никаких проблем ...

Что касается узкого места. Это метафора, если вы пытаетесь вылить большое количество жидкости из цилиндра, наклоняя его вверх дном, тогда вода уходит с постоянной скоростью. Если вы попытаетесь сделать это с бутылкой, вы заметите, что она не может сделать это так быстро. Это связано с тем, что через тонкую часть бутылки может вытекать только так много жидкости (не говоря уже о входящем в нее воздухе). Таким образом, ограничение выгрузки воды из контейнера ограничено горлышком бутылки (тонкой частью).

В программировании, когда вы говорите о бутылочном горлышке, вы говорите о самой медленной части кода. В этом случае, если ваши потоки тратят большую часть своего времени в ожидании завершения загрузки диска, то многопоточность ускоряется очень мало, так как вы можете загружать только столько сразу. Фактически, когда вы попытаетесь загрузить в 4 раза больше, вы начнете обнаруживать, что вам придется ждать примерно столько же времени, чтобы завершить загрузку. В вашем случае с одним потоком вы ждете, а когда он загружен, вы сжимаете. В случае с 4-мя потоками вы ждете примерно в 4 раза больше времени для завершения всех загрузок, а затем сжимаете все 4 файла одновременно. Вот почему вы набираете небольшую скорость. К сожалению, из-за того, что вы проводите большую часть времени в ожидании завершения нагрузки, вы не увидите ничего, приближающегося к скорости в 4 раза. Следовательно, ограничивающим фактором вашего метода является не сжатие, а загрузка файла с диска, и поэтому он называется узким местом.

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

1) Если вы загружаете файл как несколько страниц диска (обычно 2048 байт, но вы можете запросить окна, чтобы получить размер), вы получите максимально возможную производительность загрузки. Если вы загрузите размеры, не кратные этому, вы получите довольно серьезный удар по производительности.

2) Посмотрите на асинхронную загрузку. Например, вы можете загружать весь файл 2 (или больше) в память во время обработки файла 1. Это означает, что вы не ждете завершения загрузки. Однако маловероятно, что вы получите здесь огромную скорость, так как, вероятно, все равно будете ждать загрузки. Другая вещь, которую нужно попробовать - это загрузить «порции» аудиофайла асинхронно. то есть:

  • Загрузочный блок 1.
  • Начать загрузку фрагмента 2.
  • Блок процесса 1.
  • Подождите, пока загрузится блок 2.
  • Начать загрузку блока 3.
  • Блок процесса 2.
  • (и так далее)

3) Вы можете просто купить более быстрый дисковод.

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