This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6670 Cache一致性维护的问题



大家好!

目前我在做C6670,多核访问MSMC区域内的同一个数组。

环境如下:CCS v5.3、TMS320C6670、SYS/BIOS v6.33

大致想实现的功能是:申请一个全局数组,load到MSMC区域内,Core0先写这个数组,然后通知Core1去打印这个数组。

实现方法是:

1. 使用了SYS/BIOS v6.33,在起Task之前,手动地设置L2为non-cacheable,L1d为32KB cacheable

    CACHE_setL1PSize(CACHE_L1_32KCACHE);

    CACHE_setL1DSize(CACHE_L1_32KCACHE);

    CACHE_setL2Size(CACHE_0KCACHE);

2. 定义了全局变量

    #defineMSMC_test_len 256

    #pragma DATA_ALIGN   (MSMC_test, 64)

    #pragma DATA_SECTION (MSMC_test, ".shareMemotest");

     unsigned char MSMC_test[MSMC_test_len];

     由于开启了L1d cache,所以使用了

     #pragma DATA_ALIGN   (MSMC_test, 64)实现与L1d的64 Bytes Cache Line对齐

     并在CMD文件中,将该变量分配到共享存储区

     .shareMemotest  load >> MSMCSRAM

3. 在Core0的代码中,写这个全局数组

    for(i=0;i<MSMC_test_len;i++)

         MSMC_test[i] = test_cnt;

    然后,对Core0的L1d进行Write-Back再Invalidate

    CACHE_wbInvL1d ((void *) MSMC_test, MSMC_test_len, CACHE_WAIT);

4. 接着Core0向Core1发送信号

5. Core1收到这个信号后,

    CACHE_invL1d((void *) MSMC_test, MSMC_test_len, CACHE_WAIT);

    for(i=0;i<MSMC_test_len;i++)

    {

        System_printf("%d ",MSMC_test[i]);

        if(i%20 == 0)

            System_printf("\n");

    }

    首先Invalidate Core1的L1d cache,然后打印这个全局数组。

出现问题是:每次Core0对长度为256 Bytes的MSMC_test写数据,比如0x02或者0x03等等,然后通知Core1打印,Core1打印出来的是前128 Bytes正确,后面的128 Bytes都是不正确的,显示的是第一次Core0对MSMC_test写的数据。

  • 补充调试过程如下

    1. 首先Core0写全局数组MSMC_test[256],

    此时Core0还没有将L1d中的数据Write-Back到MSMC,Core1也没开始执行invalidate。所以Core1中观察这个全局数组,还是上次的数据

    2. 然后Core0执行Wite-back Invalidate,接着通知Core1。

    3. Core1收到来自Core0的通知以后,首先执行invalidate,此时再观察这个MSMC_test[256],发现数据更新了。

    至此应该说明了Core0写数据到Core0的L1d,并正确的write-back到MSMC上。而Core1 Invalidate其L1d后,此时如果Core1再去访问这个MSMC_test,就会重新去MSMC区域中去取数。

    4. 然后Core1开始打印,每打印一个Byte,都打一个断点观察

    5. 在Core1上开始打印,打印第一个Byte时候,MSMC_test[256]的前64 Bytes变灰色了

    这是因为L1d的cache line长度为64 bytes的原因嘛?

    6. Core1打印前128 Bytes一切正常,但是打印MSMC_test[256]中的第129个Byte时候,出现了下面的问题

    即从第129个Byte开始的64 Bytes,被置为了上次的数据。

    因为之前invalidate了L1d,L1d会去MSMC重新取数,cache到L1d的cache line frame。而L1d的cache line是64bytes的,所以会取64bytes的数据。

    但是打印到第129个Byte时候,重新取64Bytes结果取到了之前的数据。

    难道是Core0没有正确地将第二次的0x02 write-back到MSMC??可是在步骤3中,Core1已经能够观察到第二次的数据了!

    这是为什么啊?

  • 补充:

    1.上面描述的是测试MSMC_test这个全局数组的大小为256 Bytes,但是把这个数组大小设置为1088以上,就不会出现这个问题,一切正常。

    就是说最上面的post中设置MSMC_test_len为1088,仍然有这个问题。但是只要MSMC_test_len大于1088,就没有这个问题。比如Core0写2048 Bytes的全局数组,Core1去打印,一切正常。

    很奇怪1088是怎么来的?

    2. 如果把L1d设置为non-cacheable,无论L2是否设置为cacheable,都无需进行write-back、invalidate这些手动一致性维护操作。这是为什么?

    3. SYS/BIOS默认情况下,对L1d、L1p、L2是怎么配置的?

  • 我是新手,无法回复你的问题,不过很想有位前辈能够指导我一点,希望能加个好友。我QQ624364582

  • 搜了几个帖子,找到了方法:

    在Core1打印共享buffer之前,不仅要invalidate Core1的L1D,还要invalidate XMC的prefetch buffer,虽然CorePac手册说这样有损性能,但是目前可以。有时间再考虑怎么仔细维护这些一致性的问题。

  • 你好,我在用C6670时也碰到类似问题,但我是在一个核上运行,L2 cache与DDR3存在不一致的问题。还请指点迷津,多谢  

  • 相应的数据写之后要Writeback(cache里面的数据才会回写到内存里),读之前要invalid(读的时候就会从读内存里的数据,而不是cache里的数据).你试着这样做下,看下效果。

  • 多谢好心回答!在core 读取DDR3之前 有invalid操作,在CCS memory browser 显示L2 cache与DDR3也一致。只是处理到某个边界例如第64个32位时,L2 cache中的值突然就变化了,且变化的值并不是invlid之前的值。苦寻不到原因

  • 边界的话 我只知道L2 cache 的line size的大小是128字节,不知跟这有没有关系。我也是新手,我的QQ624364582,也是做6670的,加个好友好交流吧,可以给你推荐群,你可以去群里问问。