2013-06-05 6 views
0

Кто может сказать, в моем коде после блока while (k -) {}, почему (t1-t0) = 0?
Кто может попробовать попробовать тот же код на другом компьютере, посмотреть, показывает ли он ту же проблему?
Моя машина является HP ноутбук с
CPU: Intel P9300 2,26 х 2,
4 Гб памяти,
ОС: Ubuntu 12.04,
Linux Kernel: 3.2.0-45-родовой.
Этот скрипт является main.c gwan.gwan getus() getns() неправильный результат?

typedef struct 
{ 
    u64 a[10000000], b[10000000], c[10000000]; 

} data_t; 

char str[512]; 
u64 size; 



int main(int argc, char *argv[]) 
{ 

    data_t **data = (data_t**)get_env(argv, US_SERVER_DATA); 
             // US_VHOST_DATA); 

    if(!*data) // first time: persistent pointer is uninitialized 
    { 
     *data = (data_t*)calloc(1, sizeof(data_t)); 
     if(!*data) return 500; // out of memory 
     size = sizeof(data_t); 
     s_snprintf(str, sizeof(str)-1, "initialized data: %llu Bytes", size); 
     puts(str); 
    } 


    u64 t0, t1, timea, timeb, timediff, va, vb, vc, wa, wb, wc; 
    u64 m, j, n, k; 

    for(;;) 
    //int i=10; while(i--) 
    { 
     sleep(1); 
     //t1=0;time=0; 
     m=10000000; j=m; 
     t0 = getms(); 
     while(j--){ 
     va = __sync_add_and_fetch(&(*data)->a[1], 1); 
     vb = __sync_add_and_fetch(&(*data)->b[2], 2); 
     vc = __sync_add_and_fetch(&(*data)->c[3], 3); 
     } 
     t1 = getms(); 
     timediff = t1-t0; 
     timea = timediff ? (3*m)/(t1-t0) : m; 
 // problem code below: 
 n=m; k=n; 
     t0 = getns(); 
     while(k--){ 
     wa++; 
     wa--; 
     wa++; 
     wa--; 
     } 
     t1 = getns(); 
     timediff = t1-t0; 
     timeb = timediff ? (4*n)/(t1-t0) : n; 

     //s_snprintf(str, sizeof(str) - 1, "data[0]->a[1]:%llu, data[0]->b[2]:%llu, data[0]->c[3]:%llu, atomic add:%llu/ms, val++:%llu/ms", 
             //data[0]->a[1],  data[0]->b[2],  data[0]->c[3],  timea, timeb); 
             //va,  vb,  vc,  timea, timeb); 
     s_snprintf(str, sizeof(str) - 1, "atomic add:%llu/ms, ++val:%llu/ns, end value:%llu", 
                timea,   timeb,   wa); 
     puts(str); 
    } 
    return 0; 

Файл журнала, как показано ниже:

initialized data: 240000000 Bytes 
[Wed Jun 05 04:57:17 2013 GMT] memory footprint: 5.28 MiB. 
atomic add:35377/ms, ++val:19531/ns, end value:0 
atomic add:30674/ms, ++val:39062/ns, end value:0 
atomic add:86206/ms, ++val:10000000/ns, end value:0 
atomic add:86455/ms, ++val:10000000/ns, end value:0 
atomic add:48309/ms, ++val:10000000/ns, end value:0 
atomic add:30706/ms, ++val:10000000/ns, end value:0 
atomic add:30674/ms, ++val:10000000/ns, end value:0 
atomic add:30674/ms, ++val:10000000/ns, end value:0 
atomic add:86705/ms, ++val:10000000/ns, end value:0 
atomic add:86455/ms, ++val:10000000/ns, end value:0 
atomic add:86455/ms, ++val:10000000/ns, end value:0 
atomic add:61099/ms, ++val:10000000/ns, end value:0 
atomic add:50167/ms, ++val:10000000/ns, end value:0 
... 

только первые два результата показах значимые данные в наносекунд. Остальные - все ++ val: 10000000/ns, т. Е. T1-t0 = 0.
Та же проблема с getus().
Когда я использую getms(), t1-t0 всегда равен 0.
Примечание: вторая строка двойная от первой, то есть 19531/ns x 2 = 39062/ns.

ответ

0

Почему (t1-t0) = 0?

Этот код не особо прост в чтении.

Почему бы не начать с печати значений времени (вместо их разницы)? Затем мы увидим, почему разница равна нулю.

Возможно, что временное разрешение слишком низкое (что делает последовательные значения равными) или что вызов API не работает (возвращается 0).

Является ли пример httpdate.c G-WAN на вашей машине?

0

[SOLVED]
Нет проблем с getns().
Plz посмотреть ссылку: https://stackoverflow.com/a/11609063/1796259
Я изменил wa на летучие, и timediff, timea, timeb на тип float.
Он дал мне правильный результат, как показано ниже:

atomic add:63829.789062/ms, ++val:0.375601/ns, end value:0 
atomic add:63829.789062/ms, ++val:0.376809/ns, end value:0 
atomic add:76923.078125/ms, ++val:0.375601/ns, end value:0 
atomic add:78947.367188/ms, ++val:0.373209/ns, end value:0 
atomic add:78947.367188/ms, ++val:0.375601/ns, end value:0 
atomic add:73170.734375/ms, ++val:0.378024/ns, end value:0 
atomic add:78947.367188/ms, ++val:0.375601/ns, end value:0 
atomic add:78947.367188/ms, ++val:0.375601/ns, end value:0 
atomic add:81081.078125/ms, ++val:0.378024/ns, end value:0 
atomic add:81081.078125/ms, ++val:0.375601/ns, end value:0 

++ Вэл x5 ~ 6 быстрее, чем __syn_add_and_fetch.

+0

Благодарим вас за отправку ответа. Учитывая их преимущества, время атомарных операций не плохо. Иногда это возможно сделать быстрее, чем атомные встроенные контроллеры GCC, потому что они всегда используют защитный барьер для безопасности во всех случаях. Создавая свои собственные атомные операции в asm, вы можете сделать так, чтобы в случаях, требующих меньшей безопасности. – Gil