找回密码
 欢迎注册
查看: 12995|回复: 7

[求助] 求助 C++ 的 mode(TI)

[复制链接]
发表于 2011-4-9 22:42:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
看到某人的C++ 代码,里面有一行看不懂, 求解释~~ int64_t __attribute__((mode(TI))) a = p*q; a *= r;
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-4-10 10:28:35 | 显示全部楼层
引用自:http://stackoverflow.com/questio ... -modexx-actually-do Q:
Hi All, This arose from a question earlier today on the subject of bignum libraries and gcc specific hacks to the c language. Specifically, these two declarations were used:
  1. typedef unsigned int dword_t __attribute__((mode(DI)));
复制代码
On 32 bit systems and
  1. typedef unsigned int dword_t __attribute__((mode(TI)));
复制代码
On 64-bit systemms. I assume given this is an extension to the C language that there exists no way to achieve whatever it achieves in current (C99) standards. So my questions are simple: is that assumption correct? And what do these statements do to the underlying memory? I think the result is I have 2xsizeof(uint32_t) for a dword in 32-bit systems and 2*sizeof(uint64_t) for 64-bit systems, am I correct? Thanks for all your help,
A:
These allow you to explicitly specify a size for a type without depending on compiler or machine semantics, such as the size of 'long' or 'int'. They are described fairly well on this page. I quote from that page:
  1. QI: An integer that is as wide as the smallest addressable unit, usually 8 bits.
  2. HI: An integer, twice as wide as a QI mode integer, usually 16 bits.
  3. SI: An integer, four times as wide as a QI mode integer, usually 32 bits.
  4. DI: An integer, eight times as wide as a QI mode integer, usually 64 bits.
  5. SF: A floating point value, as wide as a SI mode integer, usually 32 bits.
  6. DF: A floating point value, as wide as a DI mode integer, usually 64 bits.
复制代码
So DI is essentially sizeof(char) * 8. Further explanation, including TI mode, can be found here (possibly better than the first link, but both provided for reference). So TI is essentially sizeof(char) * 16 (128 bits).
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-4-10 14:52:16 | 显示全部楼层
2# gxqcn 我看过了,不知道老大平时用过这个语句没
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-4-10 21:14:44 | 显示全部楼层
感觉把C++用到这种程度的一定是火星人
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-4-11 07:53:36 | 显示全部楼层
3# wayne 没用过。我倒是非常需要这样的数据结构。哪里有例程?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-4-11 08:24:08 | 显示全部楼层
本帖最后由 wayne 于 2011-4-11 08:30 编辑 5# gxqcn 好像是gcc编译器带的,这有文档: http://gcc.gnu.org/onlinedocs/gcc/X86-Built_002din-Functions.html 问题源自 projctEuler 221题的 讨论专栏里. http://projecteuler.net/index.php?section=forum&id=221 答案是1884161251122450 ,你输进去即可查看所有人的讨论, 在我的楼下,有一位C++火星人提供的代码如下:
  1. #include <cstdio>
  2. #include <set>
  3. #include <cmath>
  4. #include <vector>
  5. #include <cassert>
  6. //1805315691966540?
  7. int const cutoff = 200000;//1638400000;
  8. int64_t const len = 1000000/*cutoff+2*/; //(int64_t)cutoff*cutoff+2;
  9. int primeFac[len];
  10. int primes[len/10];
  11. int numPrimes;
  12. std::vector<int64_t> factors(int64_t v, int64_t q)
  13. {
  14. if(v == 1)
  15. return std::vector<int64_t>(1, 1);
  16. //int p = primeFac[v];
  17. int64_t p = v;
  18. for(int index = 0; primes[index] < q && index < numPrimes; ++index)
  19. if(v%primes[index] == 0)
  20. {
  21. p = primes[index];
  22. break;
  23. }
  24. int count = 0;
  25. //std::printf("* %ld %ld %ld\n", v, p, q);
  26. //assert(v < len);
  27. //while(p == primeFac[v])
  28. while(v%p == 0)
  29. {
  30. ++count;
  31. v /= p;
  32. //std::printf(" %d %d\n", v, p);
  33. }
  34. std::vector<int64_t> ret = factors(v, std::min(2+(int64_t)sqrt(v), q));
  35. int siz = ret.size();
  36. for(int c = 0; c < count; ++c)
  37. for(int s = 0; s < siz; ++s)
  38. ret.push_back(ret[s+c*siz]*p);
  39. //std::printf("/ %ld %ld %ld\n", v, p, q);
  40. return ret;
  41. }
  42. int main()
  43. {
  44. for(int i = 0; i < len; ++i)
  45. primeFac[i] = i;
  46. for(int i = 2; i < len; ++i)
  47. if(primeFac[i] == i)
  48. for(int j = i; j < len; j += i)
  49. primeFac[j] = i;
  50. numPrimes = 0;
  51. for(int i = 2; i < len; ++i)
  52. if(primeFac[i] == i)
  53. primes[numPrimes++] = i;
  54. std::vector<int64_t> test = factors(120, 120);
  55. for(std::vector<int64_t>::iterator i = test.begin(); i != test.end(); ++i)
  56. std::printf("%ld ", *i);
  57. std::printf("\n\n");
  58. std::set<uint64_t> A;
  59. // s = p+q
  60. for(int64_t q = 1; q <= cutoff; ++q)
  61. {
  62. int64_t zeroModS = q*q+1;
  63. std::vector<int64_t> S = factors(zeroModS, q);//std::min(q, 2000000000000000/(q*q)));
  64. if(q == 100000000)
  65. {
  66. std::printf("q = %ld\nS.size() = %zu\n", q, S.size());
  67. for(std::vector<int64_t>::iterator i = S.begin(); i != S.end(); ++i)
  68. std::printf(" %lu\n", *i);
  69. }
  70. //for(int sign = -1; sign <= 1; sign += 2)
  71. int sign = -1;
  72. for(std::vector<int64_t>::iterator i = S.begin(); i != S.end(); ++i)
  73. {
  74. int64_t s = sign * *i;
  75. int64_t p = s-q;
  76. int64_t r = zeroModS/s-q; //-(p*q-1)/(p+q);
  77. int64_t __attribute__((mode(TI))) a = p*q; a *= r;
  78. if(a > 1 && a < 2000000000000000 && p < 2000000000000000/*(1LL<<62)*/)
  79. A.insert(a);
  80. }
  81. }
  82. unsigned n = 0;
  83. for(std::set<uint64_t>::iterator i = A.begin(); i != A.end(); ++i)
  84. {
  85. ++n;
  86. std::printf("%lu\n", *i);
  87. if(n == 150000)
  88. {
  89. std::printf("Done\n");
  90. break;
  91. }
  92. }
  93. std::printf("set size = %zu\n", A.size());
  94. }
  95. /*
  96. int main()
  97. {
  98. int cutoff = 1000000000;
  99. std::set<uint64_t> a;
  100. for(int p = 1; p < cutoff; ++p)
  101. {
  102. int range = std::min(cutoff/p, p);
  103. for(int q = -range; q <= range; ++q)
  104. if(q != 0 && p+q != 0)
  105. {
  106. if(((int64_t)p*q-1) % (p+q) == 0)
  107. {
  108. int r = -(p*q-1)/(p+q);
  109. if(r < cutoff)
  110. a.insert(std::max((int64_t)p*q*r, -(int64_t)p*q*r));
  111. }
  112. }
  113. }
  114. a.erase(0);
  115. unsigned n = 0;
  116. for(std::set<uint64_t>::iterator i = a.begin(); i != a.end(); ++i)
  117. {
  118. ++n;
  119. std::printf("%lu\n", *i);
  120. if(n == 150000)
  121. {
  122. std::printf("Done\n");
  123. break;
  124. }
  125. }
  126. std::printf("set size = %zu\n", a.size());
  127. }
  128. */
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2011-4-11 08:51:53 | 显示全部楼层
这个限定是不是通知编译器可以向量优化?比如用MMX、SIMD、3DNow! 等汇编指令。 还有,标准C语言原生态整数类型是否最高仅支持到64位?128位的四则运算、位运算等还需要程序员自定义?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2011-4-12 17:37:36 | 显示全部楼层
7# gxqcn stackoverflow.com上的回答好像是在说,直接显式的指定一个类型的大小,而与编译器和机器类型无关。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-9-28 06:44 , Processed in 0.025460 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表