【问题标题】:What is the purpose of bitshifting by 0位移0的目的是什么
【发布时间】:2018-06-13 12:41:35
【问题描述】:

我正在审查适用于 Linux 的开源 AMD GPU 驱动程序。我注意到一些我以前从未见过的东西,我想知道它的目的。在 sid.h 文件的第 1441 行,有一系列定义是整数被左移 0。这不会导致对原始整数进行操作吗?

这里是摘录和标题的链接

    #define VGT_EVENT_INITIATOR                      0xA2A4
    #define SAMPLE_STREAMOUTSTATS1                   (1 << 0)
    #define SAMPLE_STREAMOUTSTATS2                   (2 << 0)
    #define SAMPLE_STREAMOUTSTATS3                   (3 << 0)

https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/amdgpu/sid.h#L1441

另外,我正在学习访问 AMD GPU 的性能计数器寄存器以计算 GPU 负载。对此的任何提示也将不胜感激。

【问题讨论】:

  • 这可能是由某种宏自动生成的。它可能有一个用于位域类型值的位移版本以及一个枚举类型版本。
  • 我不排除这只是代码编写方式的一个错误。我非常精通这类事情,我想不出一个很好的理由来写这个。它可能会从一个写得不好的自动代码生成器中掉出来,但即使这样也相当草率。
  • @Zalman Stern:不。如果这是为了将整数值放入位偏移0 处的手动实现的位域中,那么移位0 是一种非常好的编程实践。我会尽可能声明这是在任何自尊代码中必需
  • 好的,我可以看到,但在这种情况下,我可能会继续使用位域掩码对其进行屏蔽。

标签: c linux driver gpu performance-testing


【解决方案1】:

为了保持一致性,可以这样做(不一定适用于您的具体情况)。例如,我可以将一组单比特标志描述为

#define FLAG_1 0x01
#define FLAG_2 0x02
#define FLAG_3 0x04
#define FLAG_4 0x08

或作为

#define FLAG_1 (1u << 0)
#define FLAG_2 (1u << 1)
#define FLAG_3 (1u << 2)
#define FLAG_4 (1u << 3)

在后一种方法的第一行中,我不必移动0。但它只是看起来更一致,并强调了FLAG_1 与其他标志具有相同性质的事实。如果有一天我决定更改它,0 充当不同值的占位符。

您实际上可以在 DYN_OR_ENDYN_RR_EN 宏定义中使用 shift by 0 的链接代码中准确看到这一点。


该方法可以扩展到单词中的多位字段,例如以下(人为的)示例

// Bits 0-3 - lower counter, bits 4-7 - upper counter

#define LOWER_0  (0u << 0)
#define LOWER_1  (1u << 0)
#define LOWER_2  (2u << 0)
#define LOWER_3  (3u << 0)

#define UPPER_0  (0u << 4)
#define UPPER_1  (1u << 4)
#define UPPER_2  (2u << 4)
#define UPPER_3  (3u << 4)

unsigned packed_counters = LOWER_2 + UPPER_3; /* or `LOWER_2 | UPPER_3` */

同样,0 位的移位纯粹是为了视觉一致性。以及0 值的变化。

您实际上可以在 0LC_XMIT_N_FTSLC_XMIT_N_FTS_MASK 宏的定义中的链接代码中准确地看到这一点。

【讨论】:

  • 给出的值是线性连续的,而不是 2 的幂,所以用法非常混乱。制作概念上不同的东西——单比特标志与线性枚举——视觉上一致是没有帮助的。
  • @Zalman Stern:这可能只是意味着这些值旨在放置到位于包含字中偏移量0 的多位位字段上。请参阅上面的额外示例。
  • 出于这个原因,我通常会移动 0 .. 当然编译器只是优化它。
  • 充分利用u 形成移位值。
  • 在位域上添加上下文后,答案会好得多。再一次,如果这是使用的话,原始标题应该记录那个等等。不过,真的,我不记得曾在丰富的编程经验中看到过这种情况。我已经看到使用单个宏将值放入位域的技术,并且我已经看到使用命名常量作为移位偏移量。 (其中一个移位常数的值可能为零。)
猜你喜欢
  • 1970-01-01
  • 2014-02-28
  • 2012-08-20
  • 2018-03-04
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 2014-02-11
相关资源
最近更新 更多