| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1647 人关注过本帖
标题:C 代码优化--数组内任意长度字节的数据赋值
只看楼主 加入收藏
sgnes
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2014-10-19
结帖率:0
收藏
已结贴  问题点数:20 回复次数:5 
C 代码优化--数组内任意长度字节的数据赋值
程序代码:
具体如下:
1. 调用该函数用于把需要发送的信号放到缓冲区中,信号长度位数不定,在0-32位之间,使用如下函数把信号写入到指定的起始位,长度,定时发送,具体 参数如下,请帮忙看下该代码是否还可以优化,由于该函数调用太多,cpu使用率还是有点高,或者各位大侠有更好的方法吗,谢谢!
uint32 DATA:                   要发送的数据
uint32 CanBuffIdx:           缓冲区编号
uint8 CanBuffStartBit:  每个缓冲区8个字节,64位,发送的信号的起始位
uint16 CanBuffLength: 发送的信号的长度(位,不是字节)
uint8 *Tx_Buffer: 缓冲区地址
uint8 CanBuffOrder: 字节序




#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <windows.h>
#include <WinBase.h>
#include <ctime>

typedef unsigned char    uint8;
typedef signed char        int8;
typedef unsigned short    uint16;
typedef signed short    int16;
typedef unsigned int    uint32;
typedef signed int        int32;
typedef unsigned long    uint64;
typedef signed long        int64;

void PutMessageData(uint32 DATA, uint32 CanBuffIdx, uint8 CanBuffStartBit, uint16 CanBuffLength, uint8 *Tx_Buffer, uint8 CanBuffOrder);
void PutMessageDataNew(uint32 DATA, uint32 CanBuffIdx, uint8 CanBuffStartBit, uint16 CanBuffLength, uint8 *Tx_Buffer, uint8 CanBuffOrder);
void PutMessageDataOld(uint32 DATA,uint32 CAN_BUFF_IDX,uint8 CAN_BUFF_STARTBIT,uint16 CAN_BUFF_LENGTH,uint8 *Tx_Buffer, uint8 CAN_BUFF_ORDER);


#define INTEL 0
#define MOTO 1
#define MIXMODE 2
#define CAN_ORDER INTEL
#define MAX        32
#define MIN        1


static union /* CAN data buffer definition */
{
    uint8 data_au8[8]; /* 8-bytes data frame */
    uint64 data_u64; /* for efficient clearing of 8-bytes buffer */
} msgData[16];

#define MAX_TIME 30*100000
uint8 length_data[MAX_TIME];

using namespace std;
uint8 buff[128];

int main()
{
    uint64 i,j;
    uint32 data = 0x12345678;
    uint64 start_msec,end_msec;
    uint8 signal_length, signal_start_bit;
   

    srand(time(0));
    for (i=0; i<MAX_TIME; i++)
    {
        length_data[i] = rand() % (MAX + 1 - MIN) + MIN;
    }
    start_msec = GetTickCount();
    for (i=0; i<MAX_TIME; i++)
    {
        signal_length = //length_data[i];//
        signal_start_bit =9;//= rand() % (64 - signal_length  + 1 - 1) + 1;
        PutMessageDataOld(data,0,signal_start_bit,signal_length,buff,INTEL);
    }
    end_msec = GetTickCount();
    printf("%ld\r\n",end_msec - start_msec);

    start_msec = GetTickCount();
    for (i=0; i<MAX_TIME; i++)
    {
        signal_length = length_data[i];//
        signal_start_bit =9;//= rand() % (64 - signal_length  + 1 - 1) + 1;
        PutMessageData(data,0,signal_start_bit,signal_length,buff,INTEL);
    }
    end_msec = GetTickCount();
    printf("%ld\r\n",end_msec - start_msec);


    start_msec = GetTickCount();
    for (i=0; i<MAX_TIME; i++)
    {
        signal_length = //length_data[i];//rand() % (MAX + 1 - MIN) + MIN;
        signal_start_bit =9;//= rand() % (64 - signal_length  + 1 - 1) + 1;
        PutMessageDataNew(data,0,signal_start_bit,signal_length,buff,INTEL);
    }
    end_msec = GetTickCount();
    printf("%ld\r\n",end_msec - start_msec);
    system("pause");
}



void PutMessageData(uint32 DATA, uint32 CanBuffIdx, uint8 CanBuffStartBit, uint16
                    CanBuffLength, uint8 *Tx_Buffer, uint8 CanBuffOrder)
{
    uint8 i, j;
    uint32 send_data_32, temp_data_32 = 0xFFFFFFFF;
    uint8 stbitp1, stbitp2, send_data_8, temp_data_8;
    if((CanBuffLength > 0) && (CanBuffLength <= 32) && (CanBuffStartBit < 64))
    {
        /*For Bit*/
        if(CanBuffLength == 1)
        {
            send_data_8 = 0x01 << (CanBuffStartBit % 8);
            temp_data_8 = ~send_data_8;

            if(DATA != 0)
            {
                //send_data_8 =((uint8) (DATA<<7))>>(7-CanBuffStartBit%8);
                send_data_8 = 1 << (CanBuffStartBit % 8);
                *( Tx_Buffer + (CanBuffStartBit >> 3) + (CanBuffIdx << 3)) |= send_data_8;
            }
            else
            {
                *( Tx_Buffer + (CanBuffStartBit >> 3) + (CanBuffIdx << 3)) &= temp_data_8;
            }
        }
        /*For Intel */
        else if ((CAN_ORDER == INTEL) || ((CanBuffOrder == INTEL) && (CAN_ORDER ==
            MIXMODE)))
        {
            stbitp1 = CanBuffLength + CanBuffStartBit % 8;
            i = (stbitp1 - 1) >> 3;
            if((CanBuffLength + CanBuffStartBit <= 64) && (i < 4))
            {
                /*clear buffer*/
                temp_data_32 = (temp_data_32 >> (32 - CanBuffLength)) << (
                    CanBuffStartBit % 8);
                temp_data_32 = ~temp_data_32;
                for(j = 0; j <= i; j++)
                {
                    *( Tx_Buffer + (CanBuffStartBit >> 3) + j + (CanBuffIdx << 3)) &= (
                        uint8)temp_data_32;
                    temp_data_32 = temp_data_32 >> 8;
                }
                /*write buffer*/
                stbitp2 = 32 - CanBuffLength;
                send_data_32 = (((uint32)(DATA << stbitp2)) >> stbitp2) << (CanBuffStartBit % 8);
                for(j = 0; j <= i; j++)
                {
                    *( Tx_Buffer + (CanBuffStartBit >> 3) + j + (CanBuffIdx << 3)) |= (
                        uint8)send_data_32;
                    send_data_32 = send_data_32 >> 8;
                }
            }
        }
        /*For Moto */
        else if((CAN_ORDER == MOTO) || ((CanBuffOrder == MOTO) && (CAN_ORDER ==
            MIXMODE)))
        {
            stbitp1 = 7 - CanBuffStartBit % 8 + CanBuffLength;
            i = (stbitp1 - 1) >> 3;
            if(((stbitp1 + (CanBuffStartBit & 0xF8)) <= 64) && (i < 4))
            {
                /*clear buffer*/
                temp_data_32 = (temp_data_32 >> (32 - CanBuffLength)) << (7 - (stbitp1 - 1) % 8);
                temp_data_32 = ~temp_data_32;
                for(j = 0; j <= i; j++)
                {
                    *( Tx_Buffer + (CanBuffStartBit >> 3) + (i - j) + (CanBuffIdx << 3))
                        &= (uint8)temp_data_32;
                    temp_data_32 = temp_data_32 >> 8;
                }
                /*write buffer*/
                stbitp2 = 32 - CanBuffLength;
                send_data_32 = (((uint32)(DATA << stbitp2)) >> stbitp2) << (7 - ((stbitp1 - 1) % 8
                    ));
                for(j = 0; j <= i; j++)
                {
                    *( Tx_Buffer + (CanBuffStartBit >> 3) + (i - j) + (CanBuffIdx << 3))
                        |= (uint8)send_data_32;
                    send_data_32 = send_data_32 >> 8;
                }
            }
        }
    }
}
/*{processes...}*/
//-6-

void PutMessageDataOld(uint32 DATA,uint32 CAN_BUFF_IDX,uint8 CAN_BUFF_STARTBIT,uint16 CAN_BUFF_LENGTH,uint8 *Tx_Buffer, uint8 CAN_BUFF_ORDER)
{
    uint8 i;
    uint64 temp_data_64 ;
    uint64 send_data_64 = 0xFFFFFFFFFFFFFFFF;
    uint8 stbitp1,stbitp2;

    if(CAN_BUFF_LENGTH == 0)
    {
        return;
    }



    temp_data_64 = (uint64)DATA;


    if ((CAN_ORDER == INTEL) || ((CAN_BUFF_ORDER ==INTEL) && (CAN_ORDER == MIXMODE)))
    {

        if(CAN_BUFF_LENGTH+CAN_BUFF_STARTBIT >64)
        {
            return;
        }
        else
        {
            send_data_64 = send_data_64 >> CAN_BUFF_STARTBIT ;
            send_data_64 = send_data_64 << (64-CAN_BUFF_LENGTH ) ;
            send_data_64 = send_data_64 >> (64-CAN_BUFF_LENGTH-CAN_BUFF_STARTBIT ) ;
            send_data_64 = ~send_data_64;
            msgData[CAN_BUFF_IDX].data_u64 = send_data_64;

            for(i=0;i<8;i++)
            {

                *( Tx_Buffer+i+(CAN_BUFF_IDX << 3)) &= msgData[CAN_BUFF_IDX].data_au8[i];
            }
            temp_data_64 =  temp_data_64 << CAN_BUFF_STARTBIT ;
            msgData[CAN_BUFF_IDX].data_u64 = temp_data_64;
            for(i=0;i<8;i++)
            {

                *( Tx_Buffer+i+(CAN_BUFF_IDX << 3)) |= msgData[CAN_BUFF_IDX].data_au8[i];
            }
        }


    }
    else if((CAN_ORDER == MOTO) || ((CAN_BUFF_ORDER ==MOTO) && (CAN_ORDER == MIXMODE)))
    {
        stbitp1 = CAN_BUFF_STARTBIT % 8;
        stbitp2 = CAN_BUFF_STARTBIT >> 3;
        CAN_BUFF_STARTBIT = (7-stbitp2)*8+stbitp1;
        CAN_BUFF_STARTBIT = (CAN_BUFF_STARTBIT+1)-CAN_BUFF_LENGTH ;

        send_data_64 = send_data_64 >> CAN_BUFF_STARTBIT ;
        send_data_64 = send_data_64 << (64-CAN_BUFF_LENGTH ) ;
        send_data_64 = send_data_64 >> (64-CAN_BUFF_LENGTH-CAN_BUFF_STARTBIT) ;
        send_data_64 = ~send_data_64;
        msgData[CAN_BUFF_IDX].data_u64 = send_data_64;

        for(i=0;i<8;i++)
        {
            *( Tx_Buffer+i+(CAN_BUFF_IDX << 3)) &= msgData[CAN_BUFF_IDX].data_au8[7-i];
        }

        temp_data_64 =  temp_data_64 << CAN_BUFF_STARTBIT ;
        msgData[CAN_BUFF_IDX].data_u64 = temp_data_64;

        for(i=0;i<8;i++)
        {
            *( Tx_Buffer+i+(CAN_BUFF_IDX << 3)) |= msgData[CAN_BUFF_IDX].data_au8[7-i];
        }
    }

}
void PutMessageDataNew(uint32 DATA, uint32 CanBuffIdx, uint8 CanBuffStartBit, uint16
                       CanBuffLength, uint8 *Tx_Buffer, uint8 CanBuffOrder)
{
    uint8 i, j;
    uint32 send_data_32, temp_data_32 = 0xFFFFFFFF;
    uint8 stbitp1, stbitp2, send_data_8;
    uint8 CanbuffStartByte, CanBuffLastBits, CanBuffIdxPos, *pTxBuff = NULL;
    CanBuffLastBits = CanBuffStartBit % 8;
    CanbuffStartByte = CanBuffStartBit >> 3;
    CanBuffIdxPos = CanBuffIdx << 3;
    pTxBuff = Tx_Buffer + CanbuffStartByte + CanBuffIdxPos;
    if((CanBuffLength > 0) && (CanBuffLength <= 32) && (CanBuffStartBit < 64))
    {
        /*For Bit*/
        if(CanBuffLength == 1)
        {
            send_data_8 = 0x01 << (CanBuffLastBits);
            if(DATA != 0)
            {
                *(pTxBuff) |= send_data_8;
            }
            else
            {
                *(pTxBuff) &= (~send_data_8);
            }
        }
        /*For Intel */
        else if ((CAN_ORDER == INTEL) || ((CanBuffOrder == INTEL) && (CAN_ORDER == MIXMODE)))
        {
            stbitp1 = CanBuffLength + CanBuffLastBits;
            i = (stbitp1 - 1) >> 3;
            if((CanBuffLength + CanBuffStartBit <= 64) && (i < 4))
            {
                /*clear buffer*/
                temp_data_32 = (temp_data_32 >> (32 - CanBuffLength)) << CanBuffLastBits;
                temp_data_32 = ~temp_data_32;
                stbitp2 = 32 - CanBuffLength;
                send_data_32 = (((uint32)(DATA << stbitp2)) >> stbitp2) << (CanBuffLastBits);
                for(j = 0; j <= i; j++)
                {
                    *( pTxBuff + j) &= (uint8)temp_data_32;
                    temp_data_32 = temp_data_32 >> 8;
                    *( pTxBuff + j) |= (uint8)send_data_32;
                    send_data_32 = send_data_32 >> 8;
                }
            }
        }
        /*For Moto */
        else if((CAN_ORDER == MOTO) || ((CanBuffOrder == MOTO) && (CAN_ORDER ==
            MIXMODE)))
        {
            stbitp1 = 7 - CanBuffLastBits + CanBuffLength;
            i = (stbitp1 - 1) >> 3;
            if(((stbitp1 + (CanBuffStartBit & 0xF8)) <= 64) && (i < 4))
            {
                /*clear buffer*/
                temp_data_32 = (temp_data_32 >> (32 - CanBuffLength)) << (7 - (stbitp1 - 1) % 8);
                temp_data_32 = ~temp_data_32;
                stbitp2 = 32 - CanBuffLength;
                send_data_32 = (((uint32)(DATA << stbitp2)) >> stbitp2) << (7 - ((stbitp1 - 1) % 8));
                for(j = 0; j <= i; j++)
                {
                    *(pTxBuff + (i - j)) &= (uint8)temp_data_32;
                    temp_data_32 = temp_data_32 >> 8;
                    *(pTxBuff + (i - j)) |= (uint8)send_data_32;
                    send_data_32 = send_data_32 >> 8;
                }
            }
        }
    }
}
搜索更多相关主题的帖子: 缓冲区 
2014-10-19 20:53
sgnes
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2014-10-19
收藏
得分:0 
PutMessageDataNew是最新优化过的,相比PutMessageData效果不大,不知是否还有优化余地,谢谢!
2014-10-19 20:54
erty1001
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:331
专家分:1433
注 册:2014-8-31
收藏
得分:20 
简单说说:
                temp_data_32 = (temp_data_32 >> (32 - CanBuffLength)) << (7 - (stbitp1 - 1) % 8);
                temp_data_32 = ~temp_data_32;
                stbitp2 = 32 - CanBuffLength;
                send_data_32 = (((uint32)(DATA << stbitp2)) >> stbitp2) << (7 - ((stbitp1 - 1) % 8));
类似于这样的内容 我建议想要快的话 重新定义组织变量结构
用汇编的形式去写 就行
虽然这样写比较方便 但是编译之后 计算机运行起来就不是你能控制的速度了
2014-10-19 21:00
sgnes
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2014-10-19
收藏
得分:0 
回复 3 楼 erty1001
这是该段代码的VS2012的汇编,我们的cpu使用tricore-gcc编译器,这种代码有必要自己使用汇编写吗,
*(pTxBuff + (i - j)) &= (uint8)temp_data_32;
00161B2F 0F B6 4D FE          movzx       ecx,byte ptr [i]  
00161B33 0F B6 55 FF          movzx       edx,byte ptr [j]  
00161B37 2B CA                sub         ecx,edx  
00161B39 0F B6 45 F4          movzx       eax,byte ptr [temp_data_32]  
00161B3D 8B 55 F0             mov         edx,dword ptr [pTxBuff]  
00161B40 0F B6 0C 0A          movzx       ecx,byte ptr [edx+ecx]  
00161B44 23 C8                and         ecx,eax  
00161B46 0F B6 55 FF          movzx       edx,byte ptr [j]  
00161B4A 0F B6 45 FE          movzx       eax,byte ptr [i]  
00161B4E 2B C2                sub         eax,edx  
00161B50 8B 55 F0             mov         edx,dword ptr [pTxBuff]  
00161B53 88 0C 02             mov         byte ptr [edx+eax],cl  
                    temp_data_32 = temp_data_32 >> 8;
00161B56 8B 45 F4             mov         eax,dword ptr [temp_data_32]  
00161B59 C1 E8 08             shr         eax,8  
00161B5C 89 45 F4             mov         dword ptr [temp_data_32],eax  
                    *(pTxBuff + (i - j)) |= (uint8)send_data_32;
00161B5F 0F B6 4D FE          movzx       ecx,byte ptr [i]  
00161B63 0F B6 55 FF          movzx       edx,byte ptr [j]  
00161B67 2B CA                sub         ecx,edx  
00161B69 0F B6 45 EC          movzx       eax,byte ptr [send_data_32]  
00161B6D 8B 55 F0             mov         edx,dword ptr [pTxBuff]  
00161B70 0F B6 0C 0A          movzx       ecx,byte ptr [edx+ecx]  
00161B74 0B C8                or          ecx,eax  
00161B76 0F B6 55 FF          movzx       edx,byte ptr [j]  
00161B7A 0F B6 45 FE          movzx       eax,byte ptr [i]  
00161B7E 2B C2                sub         eax,edx  
00161B80 8B 55 F0             mov         edx,dword ptr [pTxBuff]  
00161B83 88 0C 02             mov         byte ptr [edx+eax],cl  
                    send_data_32 = send_data_32 >> 8;
00161B86 8B 45 EC             mov         eax,dword ptr [send_data_32]  
00161B89 C1 E8 08             shr         eax,8  
00161B8C 89 45 EC             mov         dword ptr [send_data_32],eax
2014-10-20 19:53
erty1001
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:331
专家分:1433
注 册:2014-8-31
收藏
得分:0 
补充一句:
我的意思是说
你要用类C语言 语句最简单的基础去组成一系列语句
这样汇编的结果,人为的能够控制一下
要不然 你怎么知道for(?d:d >dd&&ddDDD||AA++ ,pdd*!a)
之类的汇编的结果一定就是最简单 最快的形式呢
2014-10-20 20:58
erty1001
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:331
专家分:1433
注 册:2014-8-31
收藏
得分:0 
尤其是那个%运算 被C汇编器 展开之后是一大堆的东西 能不用这种运算就尽量去避免
2014-10-20 21:00
快速回复:C 代码优化--数组内任意长度字节的数据赋值
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022647 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved