Переменное время работы C-программы - PullRequest
5 голосов
/ 30 января 2011

Моя (simd) реализация занимает различное количество времени, хотя она запускается для фиксированного ввода.Время работы варьируется от, скажем, 100 миллионов тактов до 120 миллионов тактов.Программа вызывает функцию около 600 раз, и самая дорогая часть этой функции - доступ к памяти ~ 2000 раз.Таким образом, общее участие памяти в моей программе довольно высокое.

Является ли изменение во времени выполнения из-за шаблонов доступа к памяти / начального содержимого памяти?

Я использовал valgrind для анализа профиля моей программы.Это показывает, что каждый доступ к памяти занимает около 8 инструкций.Это нормально?

Ниже приведен фрагмент кода (функция), который вызывается 600 раз.Mulprev [32] [20] - это массив, к которому обращаются чаще всего.

j = 15;  
u3v = _mm_set_epi64x (0xF, 0xF);
while (j + 1)  
{

    l = j << 2;  
    for (i = 0; i < 20; i++)
    {
        val1v   = _mm_load_si128 ((__m128i *) &elm1v[i]);       
        uv  = _mm_and_si128 (_mm_srli_epi64 (val1v, l), u3v);
        u1  = _mm_extract_epi16 (uv, 0);
        u2  = _mm_extract_epi16 (uv, 4) + 16;

        for (ival = i, ival1 = i + 1, k = 0; k < 20; k += 2, ival += 2, ival1 += 2)
        {
            temp11v = _mm_load_si128 ((__m128i *) &mulprev[u1][k]); 
            temp12v = _mm_load_si128 ((__m128i *) &mulprev[u2][k]);

            val1v   = _mm_load_si128 ((__m128i *) &res[ival]);
            val2v   = _mm_load_si128 ((__m128i *) &res[ival1]); 

            bv  = _mm_xor_si128 (val1v, _mm_unpacklo_epi64 (temp11v, temp12v));
            av  = _mm_xor_si128 (val2v, _mm_unpackhi_epi64 (temp11v, temp12v));

            _mm_store_si128 ((__m128i *) &res[ival], bv);                                   
            _mm_store_si128 ((__m128i *) &res[ival1], av); 
        }
    }

    if (j == 0)
        break;
    val0v = _mm_setzero_si128 ();

    for (i = 0; i < 40; i++)
    {
        testv   = _mm_load_si128 ((__m128i *)  &res[i]);
        val1v   = _mm_srli_epi64 (testv, 60);
        val2v   = _mm_xor_si128  (val0v, _mm_slli_epi64 (testv, 4));
        _mm_store_si128 (&res[i], val2v);
        val0v   = val1v;
    }
    j--;
}       

Я хочу сократить время вычислений моей программы.Есть предложения?

Ответы [ 3 ]

3 голосов
/ 31 января 2011

Вы почти не выполняете вычисления между загрузками и хранилищами, поэтому, скорее всего, во времени выполнения будет зависеть стоимость операций ввода-вывода в / из кэша / памяти.Хуже того, ваш набор данных выглядит относительно маленьким.Вероятно, единственный способ оптимизировать эту ситуацию - улучшить схему доступа к памяти (по возможности, осуществлять доступ последовательно, и гарантировать, что строки кэша не теряются и т. Д.) И / или комбинировать эти операции с другим кодом, который работает с тем же набором данных.до / после этой процедуры (так что стоимость грузов / магазинов несколько амортизируется).

РЕДАКТИРОВАТЬ: обратите внимание, что я дал очень похожий ответ, когда вы задавали такой же вопрос для явно более ранней версии этой процедуры: Как сделать следующий код быстрее - вы, похоже, упустили момент, когда ваша главная проблема с производительностью здесь - доступ к памяти, а не вычисления.

1 голос
/ 30 января 2011

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

0 голосов
/ 30 января 2011

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

Это может быть что угодно.

...