求一个快速分解bit位的方法(续)

yaos 2008-03-11 02:52:17
http://topic.csdn.net/u/20080217/13/c99865e7-9eee-4c25-a46c-9734e7a2b41b.html?seed=814849127
接上面连接
因为上面连接速度太慢
开新战场
目前测试7种代码

DWORD find_by_yaos(DWORD a, DWORD index[33])
{
__asm
{
mov edx, a;
mov edi, dword ptr index;
xor eax, eax;
loop1:
bsr ecx, edx;
je exit1;
btr edx, ecx;
mov dword ptr [edi + 4*eax], ecx;
inc eax;
jmp loop1;
exit1:
mov dword ptr [edi + 4*eax], -1;
}
}

void find_by_yaos_1(DWORD a, DWORD index[33])
{
__asm
{
mov eax, a
mov edi, dword ptr [index]
loop1:
bsr ebx, eax
je exit1
btr eax, ebx
mov dword ptr [edi], ebx
add edi, 4
jmp loop1
exit1:
mov dword ptr [edi], -1
}
}

void find_by_yaos_2(DWORD a, DWORD index[33])
{
__asm
{
mov eax, a
mov edi, dword ptr [index]
mov ecx, 0
loop1:
shr eax, 1
jnc loop2
mov dword ptr [edi], ecx
add edi, 4
loop2:
inc ecx
cmp ecx, 32
jne loop1
mov dword ptr [edi], -1

}
}

void find_by_yaos_3(DWORD a, DWORD index[33])
{
__asm
{
mov eax, a
mov edi, dword ptr [index]
mov ecx, 32
loop1:
shl eax, 1
jnc loop2
mov dword ptr [edi], ecx
dec dword ptr [edi]
add edi, 4
loop2:
sub ecx, 1
jne loop1
mov dword ptr [edi], -1

}
}

void find_by_yaos_4(DWORD a, DWORD index[33])
{
__asm
{
mov eax, a
mov edi, dword ptr [index]
mov ecx, 32
loop1:
shl eax, 1
jnc loop2
mov dword ptr [edi], ecx
dec dword ptr [edi]
add edi, 4
loop2:
loopne loop1
mov dword ptr [edi], -1

}
}

...全文
320 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
ai_3621 2008-03-20
  • 打赏
  • 举报
回复
看来 shines 郭子

又进一步优化了liangbch的方法,

好,


DWORD find_by_GxH_L(DWORD code, int index[]) {
DWORD code_0f;
DWORD total;
char *p = (char *)index;

code_0f = code & 0x0f;
*(DWORD *)p = index_value[code_0f];
p += index_count[code_0f];;

code_0f = (code > > 4) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x04040404UL;
p += index_count[code_0f];

code_0f = (code > > 8) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x08080808UL;
p += index_count[code_0f];

code_0f = (code > > 12) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x0C0C0C0CUL;
p += index_count[code_0f];

code_0f = (code > > 16) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x10101010UL;
p += index_count[code_0f];

code_0f = (code > > 20) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x14141414UL;
p += index_count[code_0f];

code_0f = (code > > 24) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x18181818UL;
p += index_count[code_0f];

code_0f = (code > > 28) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x1C1C1C1CUL;
p += index_count[code_0f];

total = p - (char *)index;
*(DWORD *)p = (DWORD)-1;

return total;
}


难道不能在优化了么?

C也可以达到汇编的水平呵。


ai_3621 2008-03-20
  • 打赏
  • 举报
回复
DWORD find_by_GxH_L2DWORD code, int index[])
{
DWORD code_0f = code & 0x0f;
index[0] = index_value[code_0f];
int T = index_count[code_0f];

code_0f = (code >> 4) & 0x0fUL;
index[T] = index_value[code_0f] + 0x04040404UL;
T += index_count[code_0f];

code_0f = (code >> 8) & 0x0fUL;
index[T] = index_value[code_0f] + 0x08080808UL;
T += index_count[code_0f];

code_0f = (code >> 12) & 0x0fUL;
index[T] = index_value[code_0f] + 0x0C0C0C0CUL;
T += index_count[code_0f];

code_0f = (code >> 16) & 0x0fUL;
index[T] = index_value[code_0f] + 0x10101010UL;
T += index_count[code_0f];

code_0f = (code >> 20) & 0x0fUL;
index[T] = index_value[code_0f] + 0x14141414UL;
T += index_count[code_0f];

code_0f = (code >> 24) & 0x0fUL;
index[T] = index_value[code_0f] + 0x18181818UL;
T += index_count[code_0f];

code_0f = (code >> 28) & 0x0fUL;
index[T] = index_value[code_0f] + 0x1C1C1C1CUL;
T += index_count[code_0f];

return T;
}
ai_3621 2008-03-20
  • 打赏
  • 举报
回复
另:

在AMD的机器上貌似GxQ 表现最好。
yaos 2008-03-17
  • 打赏
  • 举报
回复
find_by_yaos_8 作废
指令不对

:(
yaos 2008-03-17
  • 打赏
  • 举报
回复
恩, 确实快点
到了6500数量级
fire_woods 2008-03-17
  • 打赏
  • 举报
回复
#define BIT_CHECK(NUM, MSK, INDEX) \
{ \
index[i] = INDEX; \
i += (WORD)((NUM & MSK) > > INDEX); \
}

// 作者:fire_woods
void __fastcall find_by_fire_woods(DWORD code, int index[32]) // 97
{
WORD i = 0;
...

i变量设置成DWORD会快一些,不存在转换的问题.


#define BIT_CHECK(NUM, MSK, INDEX) \
{ \
index[i] = INDEX; \
i += ((NUM >> INDEX) & 0x1 ); \
}

// 作者:fire_woods
DWORD __fastcall find_by_fire_woods(DWORD code, int index[32]) // 97
{
DWORD i = 0;
...
return i;
yaos 2008-03-17
  • 打赏
  • 举报
回复
大数据测试 1000万 无法测0x10000000, 内存占用大
Bit Random: 7771.770
yaos_2: 3736.435
yaos_3: 3892.549
yaos_4: 3806.792
yaos_5: 3649.323
yaos_6: 3673.204
yaos_7: 3890.506
yaos_8: 1946.635
GxQ: 1738.357
GxH: 1594.124
fire_wood: 7326.780

find_by_yaos_8
乃GxQ算法的循环版本

DWORD find_by_yaos_8(DWORD a, DWORD index[33])
{
__asm
{
mov edx, a
mov edi, dword ptr [index]
mov ecx, 31
xor eax, eax
loop1:
shl edx, 1
adc eax, 0
mov dword ptr [edi + 4 * eax], ecx
sub ecx, 1
jnc loop1
}
}

yaos 2008-03-17
  • 打赏
  • 举报
回复
shines把查表法用到了极限了
除非汇编化了
:)

不过还有可改进地方
yaos 2008-03-17
  • 打赏
  • 举报
回复
把GxQ算法给循环化
结果是200左右

yaos 2008-03-17
  • 打赏
  • 举报
回复
随机数字产生算法在
http://topic.csdn.net/u/20080317/09/366bddee-7fbd-4214-b27f-8a5660716210.html
yaos 2008-03-17
  • 打赏
  • 举报
回复
真随机测试
以随机化算法产生位随机整数100万个测试
Bit Random: 773.018
yaos_2: 374.173
yaos_3: 383.809
yaos_4: 380.818
yaos_5: 366.404
yaos_6: 369.125
yaos_7: 390.325
GxQ: 179.193
GxH: 161.953
fire_wood: 758.799

和以前结果有区别
跳转还是存在损失
shines77 2008-03-16
  • 打赏
  • 举报
回复
不好意思,重新看了帖子,你前面提到过不同的测试方式,用0xffffffff,这样的常量来测试并不科学,因为有可能被编译器优化,随机样本比较客观,但多少都会受Cache影响,但这也是没有办法的,影响的大小可能吧_TEST_SIZE改得很小,如256以内,让testData[]不至于占满L1 Cache,再和_TEST_SIZE比较大的值比较测试结果则可知。

所以我采用了你的第2种测试方法,不过我测试的0x10000000次,注意是十六进制的,即268435456次,不是10000000次:
for(DWORD   i   =   0;   i    <   0x10000000;   i++){  
find_by_yaos_2(i, index);// 调用bit扫描函数
}


结果如下:
find_by_lbch() computation took 10788.405 ms
find_by_GxQ() computation took 11404.145 ms
find_by_GxH() computation took 5828.546 ms
find_by_fire_woods() computation took 10128.018 ms
find_by_yaos_6() computation took 26994.502 ms

也谈不上科学,其一是没有循环2^32次,其二这只是求平均时间,实际应用当中多数是随机的输入参数,但不失为一个评判标准。
shines77 2008-03-16
  • 打赏
  • 举报
回复
奇怪,yaos,你的代码5,6,7在我的机器上表现都很慢。。。7稍微快一点,3800ms左右,打开ICC编译结果差不多

find_by_lbch() computation took 2071.550 ms
find_by_GxQ() computation took 749.953 ms
find_by_GxH() computation took 421.365 ms
find_by_fire_woods() computation took 688.288 ms
find_by_yaos_6() computation took 4133.637 ms

我想你的测试结果和GxQcn的不同之处是他用了随机的数字来测试,而你好像是从1到1000000测试,GxQcn代码:

    testData = (DWORD *)malloc( _TEST_SIZE * sizeof( DWORD ) );
srand(GetTickCount());
for ( i=0; i<_TEST_SIZE; i++ ) {
testData[i] = ( (DWORD)(rand()) << 17 ) | rand(); // 确保可充满32bits
}
无心人 2008-03-16
  • 打赏
  • 举报
回复
新的8没测试呢, 仅用来展示下思想
昨天刚想好
你测试用5, 6, 7
重点是6
7仅是个尝试
在没想到如何省略点多余的shl情况下,根本不占优势
无心人 2008-03-16
  • 打赏
  • 举报
回复
明天发个帖子求一个均匀的bit数字产生算法
:)
无心人 2008-03-16
  • 打赏
  • 举报
回复
我那里存在跳转
最后是这么测试的
设变量n
分别赋FFFFFFFF AAAAAAAA 0测试的跳转的不同情况

还有就是随循环测试i

因为没好方法得到均匀的随机32bit所以没测试随机数据
可以考虑用你们的算法测下随机
无心人 2008-03-16
  • 打赏
  • 举报
回复
呵呵
我就是在XEON2上测试的
除了随机测试哇外
结果5, 6怎么比较都比GxQ的好点

现在看到你的测试
我会重新测试随机测试的
还要加上8

估计是CPU差异导致的
shines77 2008-03-16
  • 打赏
  • 举报
回复
所以我觉得要尽量减少或不使用循环和条件判断/跳转,尽量减少内存的读/写次数,看yaos的汇编代码里还好多跳转
shines77 2008-03-16
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define _TEST_SIZE 0x1000000

DWORD bits[32];
static int index_value[16];
static int index_count[16];

// 作者:liangbch
void __fastcall find_by_lbch(DWORD code, int index[32]) //22
{
int i=0;

// 此处代码省略,详细查看旧帖51-52楼

}

#define BIT_CHECK(NUM, MSK, INDEX) \
{ \
index[i] = INDEX; \
i += (WORD)((NUM & MSK) >> INDEX); \
}

// 作者:fire_woods
void __fastcall find_by_fire_woods(DWORD code, int index[32]) // 97
{
WORD i = 0;
BIT_CHECK(code, 0x1, 0);
BIT_CHECK(code, 0x2, 1);
BIT_CHECK(code, 0x4, 2);
BIT_CHECK(code, 0x8, 3);
BIT_CHECK(code, 0x10, 4);
BIT_CHECK(code, 0x20, 5);
BIT_CHECK(code, 0x40, 6);
BIT_CHECK(code, 0x80, 7);
BIT_CHECK(code, 0x100, 8);
BIT_CHECK(code, 0x200, 9);
BIT_CHECK(code, 0x400, 10);
BIT_CHECK(code, 0x800, 11);
BIT_CHECK(code, 0x1000, 12);
BIT_CHECK(code, 0x2000, 13);
BIT_CHECK(code, 0x4000, 14);
BIT_CHECK(code, 0x8000, 15);
BIT_CHECK(code, 0x10000, 16);
BIT_CHECK(code, 0x20000, 17);
BIT_CHECK(code, 0x40000, 18);
BIT_CHECK(code, 0x80000, 19);
BIT_CHECK(code, 0x100000, 20);
BIT_CHECK(code, 0x200000, 21);
BIT_CHECK(code, 0x400000, 22);
BIT_CHECK(code, 0x800000, 23);
BIT_CHECK(code, 0x1000000, 24);
BIT_CHECK(code, 0x2000000, 25);
BIT_CHECK(code, 0x4000000, 26);
BIT_CHECK(code, 0x8000000, 27);
BIT_CHECK(code, 0x10000000, 28);
BIT_CHECK(code, 0x20000000, 29);
BIT_CHECK(code, 0x40000000, 30);
BIT_CHECK(code, 0x80000000, 31);
}

// 作者:GxQ;
// 返回返回当前bit=1的数目
DWORD find_by_GxQ(DWORD code, int index[33])
{
// 代码省略,详看旧帖68楼
}

// 作者:GxH, 查表法, index保存在char数组, 这是该方法的特点
// 原理类似liangbch的方法, 但实现方法不一样
DWORD find_by_GxH(DWORD code, int index[]) {
DWORD code_0f;
DWORD total;
char *p = (char *)index;

code_0f = code & 0x0f;
*(DWORD *)p = index_value[code_0f];
p += index_count[code_0f];;

code_0f = (code >> 4) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 4;
p += index_count[code_0f];

code_0f = (code >> 8) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 8;
p += index_count[code_0f];

code_0f = (code >> 12) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 12;
p += index_count[code_0f];

code_0f = (code >> 16) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 16;
p += index_count[code_0f];

code_0f = (code >> 20) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 20;
p += index_count[code_0f];

code_0f = (code >> 24) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 24;
p += index_count[code_0f];

code_0f = (code >> 28) & 0x0fUL;
*(DWORD *)p = index_value[code_0f] + 0x01010101UL * 28;
p += index_count[code_0f];

total = p - (char *)index;
*(DWORD *)p = (DWORD)-1;

return total;
}

int main(int argc, char * argv[])
{
LARGE_INTEGER lTimestart, lTimeEnd, liFreq;
double dbMs;

DWORD *testData;
DWORD i, j;
int index[33];

DWORD c, bitMask = 1;

for (i = 0; i < 31; i++) {
bits[i] = bitMask;
bitMask <<= 1;
}

DWORD shift, count;
for ( i = 0; i < 16; i++ ) {
bitMask = 1;
shift = 1;
count = 0;
index_value[i] = 0;
for ( j = 0; j < 4; j++ ) {
if ( (i & bitMask) != 0 ) {
index_value[i] += j * shift;
shift <<= 8;
count++;
}
bitMask <<= 1;
}
index_count[i] = count;
}

::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

testData = (DWORD *)malloc( _TEST_SIZE * sizeof( DWORD ) );
srand(GetTickCount());
for ( i=0; i<_TEST_SIZE; ++i ) {
testData[i] = ( (DWORD)(rand()) << 17 ) | rand(); // 确保可充满32bits
}

#if 1
// 对比测试函数1
{
QueryPerformanceCounter(<imestart);
for (i = 0; i < _TEST_SIZE; i++) {
find_by_lbch(testData[i], index); // 调用bit扫描函数
}
QueryPerformanceCounter(<imeEnd);
QueryPerformanceFrequency(&liFreq);

dbMs = ((double)(lTimeEnd.QuadPart - lTimestart.QuadPart) * 1000) / (double)liFreq.QuadPart;
printf("find_by_lbch() computation took %.3f ms\n", dbMs);
}
#endif

#if 1
// 对比测试函数2
{
QueryPerformanceCounter(<imestart);
for (i = 0; i < _TEST_SIZE; i++) {
find_by_GxQ(testData[i], index); // 调用bit扫描函数
}
QueryPerformanceCounter(<imeEnd);
QueryPerformanceFrequency(&liFreq);

dbMs = ((double)(lTimeEnd.QuadPart - lTimestart.QuadPart) * 1000) / (double)liFreq.QuadPart;
printf("find_by_GxQ() computation took %.3f ms\n", dbMs);
}
#endif

#if 1
// 对比测试函数3
{
QueryPerformanceCounter(<imestart);
for (i = 0; i < _TEST_SIZE; i++) {
find_by_GxH(testData[i], index); // 调用bit扫描函数
}
QueryPerformanceCounter(<imeEnd);
QueryPerformanceFrequency(&liFreq);

dbMs = ((double)(lTimeEnd.QuadPart - lTimestart.QuadPart) * 1000) / (double)liFreq.QuadPart;
printf("find_by_GxH() computation took %.3f ms\n", dbMs);
}
#endif

#if 1
// 对比测试函数4
{
QueryPerformanceCounter(<imestart);
for (i = 0; i < _TEST_SIZE; i++) {
find_by_fire_woods(testData[i], index); // 调用bit扫描函数
}
QueryPerformanceCounter(<imeEnd);
QueryPerformanceFrequency(&liFreq);

dbMs = ((double)(lTimeEnd.QuadPart - lTimestart.QuadPart) * 1000) / (double)liFreq.QuadPart;
printf("find_by_fire_woods() computation took %.3f ms\n", dbMs);
}
#endif

//*/

//system("Pause");

/*
// 对比测试函数5, yaos的代码运行出错,省略,我找的是旧帖里的代码,新帖版本太多
{
QueryPerformanceCounter(<imestart);
for(i = 0; i < _TEST_SIZE; i++) {
find_by_yaos1(testData[i], (DWORD *)&index[0], &c); // 调用bit扫描函数
}
QueryPerformanceCounter(<imeEnd);
QueryPerformanceFrequency(&liFreq);

dbMs = ((double)(lTimeEnd.QuadPart - lTimestart.QuadPart) * 1000) / (double)liFreq.QuadPart;
printf("find_by_yaos1() computation took %.3f ms\n", dbMs);
}
*/

free( testData );

system("Pause");
return 0;
}
shines77 2008-03-16
  • 打赏
  • 举报
回复
其实我刚看到这个题目,直接想到的就是查表法,没各位的创新意识,不过查表法要做好才行,yaos旧帖里后面贴的那个查表法效率就不够好。

这里贴个我写的,优点是减少写入内存的次数,共9次(包括最后写入结束标志位),其他是16次加法运算,16次访问内存(查表),这个部分是查表法必须要做的事情,即使数据存在于 L1 Cache 中,也会有一定的CPU时钟消耗,不同的CPU所用的时钟周期不一样,P4约为7个左右。缺点:最大的缺点就是要查表,访问内存,这个部分是最大的消耗,不过对于现在流行的CPU,不会有太大的问题,表的数据量也仅为 16 * 4 * 2 = 128 字节。其实还可以构造一个更大的表,如index_value[8][16], 这样, .... + 0x01010101UL * 4 这部分的代码就可以省掉,应该会更快一些。不过如果是内存很吃紧的系统上还是用小的表比较好。

测试结果如下:
find_by_lbch() computation took 2082.872 ms
find_by_GxQ() computation took 761.370 ms
find_by_GxH() computation took 437.261 ms
find_by_fire_woods() computation took 695.960 ms

如果find_by_GxH()使用__fastcall 则可更快,380~390ms左右

测试环境 VC 6.0 sp5, WinXP SP2, P4 3.0G, 1G RAM

还发现一个问题,如果用ICC 10.1编译的话,会比VC 6.0更快,不过有时候如去掉find_by_GxQ()不编译,find_by_GxH速度反而变慢,所以运行速度不可过于迷信,要看编译器,要看测试环境的硬件(CPU等),我开ICC /fast编译选项反而变慢。

内容太长贴不上来,分几次。。。
加载更多回复(9)
一、Docker解决了什么问题?         一款产品从开发到上线,从操作系统,到环境运行,在到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司不得不面对的问题,特别是各版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。         Docker对此给出了一个标准化的解决方案。         环境配置如此麻烦,换一台机器,就要重来一次,费力费时。那么软件可以不可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用Docker可以消除协作编码时“在我的机器上可以正常工作”的问题。           传统上认为,软件编码开发/测试结束后,所产出的成果就是程序或是能够编译执行的二进制字节码等。而为了让这些程序可以顺利执行,开发团队也得准备完善的部署文件,让运维团队得以部署应用程序,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然经常发生部署失败的情况。Docker镜像的设计,使得Docker得以打破过去【程序即应用】的观念。透过镜像(image)将作业系统核心除外,运作应用程序所需要的系统环境,由上而下打包,达到应用程序快平台的无法接轨运作。 二、Docker是个啥         Docker是基于Go语言实现的云开源项目。         Docker的主要目标是“Build,Ship and Run Any APP,Anywhere”,也就是通过对应组件的封装、分发、部署、运行等生命周期的管理,是用户的App及其运行环境能够做到“一次封装,到处运行”。         Linux容器技术的出现就解决了这样一个问题,而Docker就是在它的基础上发展过来的。将应用运行的Docker容器上面,而Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机器上就可以一键部署好,大大简化了操作         Docker解决了运行环境和配置软件容器,方便做持集成并有助于整体发布的容器虚拟化技术。 三、虚拟机与Docker         虚拟机就是带环境安装的一种解决方案。         它可以在一种操作系统里面运行另一种操作系统,比如在windows系统里运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去就跟真实的系统一样,能够使应用程序,操作系统和硬件三者之间逻辑不变   虚拟机的缺点: 资源占用多 冗余步骤多启动慢 由于虚拟机存在这些缺点,Linux发展出了另一种虚拟化技术:Linux容器(LinuxContainers,缩写为LXC)。         Linux容器不是模拟一个完整的操作系统,而是对进程进程进行隔离。有了容器就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆包一整套操作系统,只需要软件工程所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一的工作。   比较了Docker和传统虚拟机方式的不同之处: 传统虚拟机技术是虚拟机出一套硬件后,在其上运行一个完整操作系统,在该系统上在运行所需应用进程; 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。每个容器之间相互隔离,每个容器有自己的文件系统,容器之间进程不会互相影响,能区分计算字资源。   四、开发/运维(DevOps) 更快速的应用交付和部署 更便捷的升级和扩缩容 更简单的系统运维 更高效的计算资源利用   五、Docker安装 Docker支持一下的CentOS版本: CentOS 7(64-bit) CentOS 6.5(64-bit)或更高版本   目前,CentOS仅发行版中的内核支持Docker。 Docker运行在CentOS7上,系统内核版本为3.10以上 Docker运行在CentOS6.5或更高版本,系统内核版本为2.6.32-431或跟高的版本 使用uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)   六、Docker的基本组成   Docker镜像(image)就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。 Docker容器(Container)独立运行的一个或一组应用。容器就是镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个建议的Linux环境和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上层那一层是可读可写的。 Docker仓库(Repository)是集中存放镜像文件的场所。仓库和仓库注册服务器是有区别的。仓库注册服务器上往往存放着很多个仓库,每一个仓库又包含了多个镜像,每个镜像有不同的的标签(tag)。仓库分为公开仓库和私有仓库两种形式。最大的公开仓库是DockerHub         Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序或配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。可以生成多个同时运行的容器实例。   七、安装Docker(CentOS7) 参考官网:https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/ 1.卸载旧版本(没有装过可以直接跳过) sudo yum remove docker     docker-common     docker-selinux     docker-engine2. 安装所需的软件包 sudo yum install -y yum-utils device-mapper-persistent-data lvm23.设置stable镜像仓库 sudo yum-config-manager     --add-repo     https://download.docker.com/linux/centos/docker-ce.repo4.启用edge和testing镜像仓库(可选) sudo yum-config-manager --enable docker-ce-edgesudo yum-config-manager --enable docker-ce-testing5.更新yml的软件索引 sudo yum makecache fast6.安装最新的DockerCE sudo yum install docker-ce7.启动Docker sudo systemctl start docker8.采用阿里云镜像加速(可选) 访问https://dev.aliyun.com/search.html 注册阿里云账号,并登陆 点击进入管理中心,找到镜像加速区 根据阿里云提示修改Docker配置 9.测试安装是否成功,运行HelloWord镜像 sudo docker run hello-world  运行成功! 10.Docker运行步骤    

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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