栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

多线程random_r比单线程版本慢

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程random_r比单线程版本慢

一个非常简单的更改以将数据分配到内存中:

struct random_data* rand_states = (struct random_data*)calloc(NTHREADS * 64, sizeof(struct random_data));char* rand_statebufs = (char*)calloc(NTHREADS*64, PRNG_BUFSZ);pthread_t* thread_ids;int t = 0;thread_ids = (pthread_t*)calloc(NTHREADS, sizeof(pthread_t));for (t = 0; t < NTHREADS; t++) {    initstate_r(random(), &rand_statebufs[t*64], PRNG_BUFSZ, &rand_states[t*64]);    pthread_create(&thread_ids[t], NULL, &thread_run, &rand_states[t*64]);}

导致我的双核计算机上的运行时间大大缩短。

这将证实它要测试的怀疑-您正在两个单独的线程中对同一高速缓存行中的值进行突变,因此具有高速缓存争用。赫伯·萨特(Herb Sutter)的“机器体系结构-您的编程语言从未告诉过您的话题”值得一看,如果您还有时间不知道的话,他演示了从1:20左右开始的虚假共享。

计算您的缓存行大小,并创建每个线程的数据,使其与之对齐。

将线程的所有数据整理到一个结构中,然后对齐它会更干净一些:

#define CACHE_LINE_SIZE 64struct thread_data {    struct random_data random_data;    char statebuf[PRNG_BUFSZ];    char padding[CACHE_LINE_SIZE - sizeof ( struct random_data )-PRNG_BUFSZ];};int main ( int argc, char** argv ){    printf ( "%zdn", sizeof ( struct thread_data ) );    void* apointer;    if ( posix_memalign ( &apointer, sizeof ( struct thread_data ), NTHREADS * sizeof ( struct thread_data ) ) )        exit ( 1 );    struct thread_data* thread_states = apointer;    memset ( apointer, 0, NTHREADS * sizeof ( struct thread_data ) );    pthread_t* thread_ids;    int t = 0;    thread_ids = ( pthread_t* ) calloc ( NTHREADS, sizeof ( pthread_t ) );        for ( t = 0; t < NTHREADS; t++ ) {        initstate_r ( random(), thread_states[t].statebuf, PRNG_BUFSZ, &thread_states[t].random_data );        pthread_create ( &thread_ids[t], NULL, &thread_run, &thread_states[t].random_data );    }    for ( t = 0; t < NTHREADS; t++ ) {        pthread_join ( thread_ids[t], NULL );    }    free ( thread_ids );    free ( thread_states );}

CACHE_LINE_SIZE
64:

refugio:$ gcc -O3 -o bin/nixuz_random_r src/nixuz_random_r.c -lpthreadrefugio:$ time bin/nixuz_random_r 6463499495944240966real    0m1.278suser    0m2.540ssys 0m0.000s

或者,您可以使用两倍的缓存行大小,并使用malloc-额外的填充可确保变异的内存位于单独的行上,因为malloc为16(IIRC),而不是64字节对齐。

(我将ITERATIONS减少了十倍,而不是拥有笨拙的机器)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/391776.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号