大家都这么积极,我也贴出我的第一期的答卷,没有使用Intel tbb技术,使用双向链表,先载入数据到内存,然后再计算,废话少说,看源码!

whhappy 2008-02-14 03:00:54
#include <math.h>
#include <stdio.h>
#include <process.h>
#include <stdlib.h>
#include<time.h>
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
using namespace std;
typedef struct node
{
int nodeid;
char name[63];
struct node * prep;
struct node * next;
} NODE,*Linklist;
int Total;
Linklist head,rhead,nhead;

void InputDataFromFile()
{
char tmp1[63];
FILE * fp = fopen("Students.in", "r");
if (fp==NULL)
{
printf("Can't open Students.in file!\n");
system("PAUSE");
exit(-1);
}
fscanf(fp, "%d\r\n",&Total);
head=(NODE*)malloc(sizeof(NODE)*Total); // Allocates memory blocks for all data
rhead=head;
nhead=head;
for(int i = 0;i <Total; i++)
{
fgets(tmp1, 63, fp);
sprintf(head->name,"%s",tmp1);
head->nodeid=i;
if (i==0)
{
head->prep=NULL;
}
else
head->prep=head-1;
if (i!=Total-1)
{
head->next=head+1;
head=head->next;
}
else
head->next=NULL;

}
}

double EvaluateRooms()
{
Linklist np1=rhead;
int rt = 0;
while (np1!=NULL)
{
Linklist np2=np1->next;
float sum = 0;
for(int j = 11; j < 61; j++)
{
sum += abs((int)np1->name[j] - (int)np2->name[j]);
}
rt += sum;
np1=np2->next;
}
return (double)rt/(double)200;
}

inline int ComputeTwoPointsValueV2(Linklist np1,Linklist np2)
{
int rt=0;
for (int j=11;j<61;j++)
{
rt+=abs((int)np1->name[j] - (int)np2->name[j]);
}
return rt;
}

inline int TestDistAfterChange(Linklist np1,Linklist np2)
{
int beforechange=0,afterchange=0;
Linklist npt1,npt2;
int np1nodeid,np2nodeid;
np1nodeid=np1->nodeid;
np2nodeid=np2->nodeid;
if (np1==np2) return 0;
if ((np1nodeid<np2nodeid)&&(np1nodeid%2==0)&&(abs(np1nodeid-np2nodeid)==1)) return 0;
if ((np1nodeid>np2nodeid)&&(np2nodeid%2==0)&&(abs(np1nodeid-np2nodeid)==1)) return 0;
if (np1nodeid%2==0)
npt1=np1->next;
else
npt1=np1->prep;
if (np2nodeid%2==0)
npt2=np2->next;
else
npt2=np2->prep;

beforechange=ComputeTwoPointsValueV2(np1,npt1)+ComputeTwoPointsValueV2(np2,npt2);
afterchange=ComputeTwoPointsValueV2(np2,npt1)+ComputeTwoPointsValueV2(np1,npt2);
return afterchange-beforechange;//
}
void SwapPoint(Linklist np1,Linklist np2)
{
if (np1->nodeid==0)
rhead=np2;
if (np2->nodeid==0)
rhead=np1;
int nid=0;


Linklist np1pre=np1->prep;
Linklist np1next=np1->next;
Linklist np2pre=np2->prep;
Linklist np2next=np2->next;

if (np1->nodeid-np2->nodeid==-1)
{
np1next=np1;
np2pre=np2;
}
if (np1->nodeid-np2->nodeid==1)
{
np2next=np2;
np1pre=np1;
}
if (np1pre!=NULL) np1pre->next=np2;
if (np1next!=NULL) np1next->prep=np2;
if (np2pre!=NULL) np2pre->next=np1;
if (np2next!=NULL) np2next->prep=np1;

np2->prep=np1pre;
np2->next=np1next;
np1->prep=np2pre;
np1->next=np2next;

nid=np1->nodeid;
np1->nodeid=np2->nodeid;
np2->nodeid=nid;
}
void ComputeRoomAssignmentsV2()
{
srand((unsigned)time(0));
long s=0,change_sum=1,computetimes=0;
double StartT=1,EndT=100000;
srand( (unsigned)time( 0 ) );
long int outsum=Total*10;
while(EndT>StartT)
{
int d1=GetRandom(0,Total-1);
int d2=GetRandom(0,Total-1);
Linklist np1=nhead+d1;
Linklist np2=nhead+d2;
int rt=TestDistAfterChange(np1,np2);
if (rt<0)
{
SwapPoint(np1,np2);
//swap the data in memory
if (change_sum>1)
EndT=EndT*(1-(double)1/change_sum);
s=0;
change_sum++;
}
else
if (rt!=0) //if is not 0 then show this time is valiable swap computing but not use it
s++;
computetimes++;
if (s==100000)
break;
}
printf("The total change times is %d \nTotal compute times is %d\nNochange times is %d\nEndT is %g\n",change_sum,computetimes,s,EndT);
}

void PrintRoomAssignmentToFile()
{
char name[30];
FILE *outf=freopen("Assignments.out", "w", stdout);
Linklist np2=rhead;
while (np2!=NULL)
{
sprintf(name,"%.10s",np2->name);
fprintf(outf,"%s\n",name);
np2=np2->next;
}
fclose(outf);
}

int main()
{
float final,first;
clock_t start,end;
InputDataFromFile();
first=EvaluateRooms();
printf("The initial Disharmony is %g\n",first);
start=clock();
ComputeRoomAssignmentsV2();
end=clock();
printf("The time to computer room assignments is %g seconds\n",(double)(end-start)/CLOCKS_PER_SEC);
final=EvaluateRooms();
printf("Final Disharmony is %g\n",final);
printf("press enter to exit!");
PrintRoomAssignmentToFile();
getchar();
return 0;
}
纯单线程,速度还可以。大家多提意见
...全文
123 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
sapzj1984 2008-02-18
  • 打赏
  • 举报
回复
顶!
sapzj1984 2008-02-16
  • 打赏
  • 举报
回复
dobear_0922 2008-02-15
  • 打赏
  • 举报
回复
看看,支持下!
whhappy 2008-02-15
  • 打赏
  • 举报
回复
強人!
denghui0815 2008-02-14
  • 打赏
  • 举报
回复
inline   int   ComputeTwoPointsValueV2(Linklist   np1,Linklist   np2) 
{
int rt=0;
for (int j=11;j <61;j++)
{
rt+=abs((int)np1-> name[j] - (int)np2-> name[j]);
}
return rt;
}

这个一定要用sse指令优化

#define XGETM128_UINT16(Val, Index) (((const unsigned short*)&Val)[Index])
uint8 XGetDisharmonyCore(const char* pAnswerA, const char* pAnswerB)
{
__m128i xDisharmony = _mm_sad_epu8(((const __m128i*)pAnswerA)[0], ((const __m128i*)pAnswerB)[0]);
xDisharmony = _mm_add_epi16(xDisharmony, _mm_sad_epu8(((const __m128i*)pAnswerA)[1], ((const __m128i*)pAnswerB)[1]));
xDisharmony = _mm_add_epi16(xDisharmony, _mm_sad_epu8(((const __m128i*)pAnswerA)[2], ((const __m128i*)pAnswerB)[2]));
xDisharmony = _mm_add_epi16(xDisharmony, _mm_sad_epu8(((const __m128i*)pAnswerA)[3], ((const __m128i*)pAnswerB)[3]));
return (uint8)(XGETM128_UINT16(xDisharmony, 0) + XGETM128_UINT16(xDisharmony, 4));
}
zm0011 2008-02-14
  • 打赏
  • 举报
回复
我没参加第一期题目,对程序不妄加评论。不过,这个比赛的根本目的是推广INTEL TBB,按照比赛规则,使用INTEL技术(包括TBB, Intel C++ compiler,IPP, OpenMP等)最多有100分的加分。另外,单线程程序在多核CPU上测试是完全没有优势的,就是说别人的多线程程序在“理想”状况下,可能比你块1~2倍(双核)或3~4倍(4核)。

566

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧